[英]How to parse a JNI signature?
如何獲取JNI簽名(方法)的一般信息?
例如,
一個方法的JNI簽名是Lme/jni/Clazz;->demo(Ljava/lang/String;IZ[I[[Z)V
,我想知道這個方法真正的簽名是什么,也就是me.jni.Clazz: void demo(java.lang.String,int,boolean,int[],boolean[][])
。 對我來說,困難的部分是解析方法參數的類型,因為原始類型不容易拆分,沒有用;
分隔。 . 在此示例中,它是IZ[I[[Z
。
我想知道是否有任何庫可以解決這個問題,或者你可以給我一些解決上述問題的建議。
您可以將描述符解析為MethodTypeDesc
。 例如使用jshell
:
> jshell
| Welcome to JShell -- Version 18.0.1
| For an introduction type: /help intro
jshell> import java.lang.constant.*
jshell> MethodTypeDesc.ofDescriptor("(Ljava/lang/String;IZ[I[[Z)V")
$2 ==> MethodTypeDesc[(String,int,boolean,int[],boolean[][])void]
jshell>
正如我在評論中觀察到的,您正在查看的(大部分)是 Java VM 的類型簽名表示。 JNI雖然用了一些,但不屬於JNI。 它的主要文檔在Java VM 規范的第 4.3 節中。 這提供了正式的語法和簡短的散文描述。
對我來說,困難的部分是解析方法參數的類型,因為原始類型不容易拆分,沒有用
;
分隔。 .
所有參數類型之間都沒有用分號分隔。 一個;
您看到的是java.lang.String
類型參數的簽名的一部分,總體上是Ljava/jang/String;
. 您確實需要從左到右閱讀此類類型簽名,但只要您這樣做,它們就不會產生歧義。 從上下文中總是很清楚列表中每個單獨的描述符在哪里結束,下一個緊隨其后。
特別是,基本類型具有單字母簽名。 它們列在規范的鏈接部分中。 數組簽名的形式為[
緊跟組件類型的簽名。 類(包括接口)類型簽名的形式為L
,后跟類型的“二進制名稱”,以分號 ( ;
) 結尾。
方法簽名的形式為()
- 參數類型的零個或多個類型描述符的封閉列表(如上所述),緊隨其后的是返回類型的描述符。
一個方法的JNI簽名是
Lme/jni/Clazz;->demo(Ljava/lang/String;IZ[I[[Z)V
,
不,不是。 我們所說的那種簽名只描述了類型,而不是名稱或主機類。 在那個例子中,它是(Ljava/lang/String;IZ[I[[Z)V
。 據我所知,Java VM 和 JNI 都沒有使用您提供的完整形式,盡管它的構造看起來相對清晰。 我可以想象各種工具發出的形式。
Lme/jni/Clazz;
是引用類型me.jni.Class
的簽名。 據推測, ->demo
表示名為“demo”的類的成員,其類型由字符串的其余部分給出。
(
... )V
是返回void
( V
) 的方法的描述符形式。 這種情況下的參數類型是
Ljava/lang/String;
- java.lang.String
。 我們從L
中認識到它是一個類類型。 類型的(二進制)名稱如下,我們通過;
識別描述符的結尾。 . 二進制名稱是普通的 Java 類名稱,除了使用/
代替.
作為名稱分隔符,使用 Java VM 修改后的 UTF-8 編碼進行編碼。I
int
。 這是一個單字母代碼,所以我們不需要四處尋找結尾。Z
boolean
。 這是另一個單字母代碼。[I
- int
( I
) 的數組 ( [
),又名int[]
。 我們從[
中識別出它是一個數組類型,緊隨其后的是其元素類型的描述符。[[Z
- array ( [
) of (array ( [
) of boolean
( Z
)),又名boolean[][]
。 這遵循與之前相同的遞歸規則。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.