JNI类型签名和方法签名

来源:互联网 发布:网络电话攻击软件 编辑:程序博客网 时间:2024/05/08 07:17

一、基本数据类型

Paste_Image.png

二、引用数据类型

Paste_Image.png

注意:
1、引用数据类型则不能直接使用,需要根据JNI函数进行相应的转换后,才能使用
2、多维数组(包括二维数组)都是引用类型,需要使用 jobjectArray 类型存取其值 ;
例如:二维整型数组就是指向一位数组的数组,其声明使用方式如下:

 //获得一维数组 的类引用,即jintArray类型    jclass intArrayClass = env->FindClass("[I");     //构造一个指向jintArray类一维数组的对象数组,该对象数组初始大小为dimion    jobjectArray obejctIntArray  =  env->NewObjectArray(dimion ,intArrayClass , NULL);    ...//具体操作

Paste_Image.png

三、描述符

3.1 类描述符
类描述符是类的完整名称(包名+类名),将原来的 . 分隔符换成 / 分隔符。

例如:在java代码中的java.lang.String类的类描述符就是java/lang/String
其实,在实践中,我发现可以直接用该类型的域描述符取代,也是可以成功的。
例如:

jclass intArrCls = env->FindClass("java/lang/String")

等同于

jclass intArrCls = env->FindClass("Ljava/lang/String;")

数组类型的描述符则为,则为: [ + 其类型的域描述符 (后文说明)

例如:

int [ ]     其描述符为[Ifloat [ ]   其描述符为[FString [ ]  其描述符为[Ljava/lang/String;

3.2域描述符

3.2.1基本类型的描述符已经被定义好了,如下表所示:

Paste_Image.png

这里容易搞混淆的是Boolean和long为什么不取首字母。因为byte已经是B,所以B被占了,Boolean选择用Z。Long为什么不用L,因为L表示对象,被占用,选择用J

3.2.2引用类型的描述符

一般引用类型则为 L + 该类型类描述符 + ; (注意,这儿的分号“;”只得是JNI的一部分,而不是我们汉语中的分段,下同)

例如:String类型的域描述符为 Ljava/lang/String;
对于数组,其为 : [ + 其类型的域描述符 + ;

int[ ]     其描述符为[Ifloat[ ]   其描述符为[FString[ ]  其描述符为[Ljava/lang/String;Object[ ]类型的域描述符为[Ljava/lang/Object;

多维数组则是 n个[ +该类型的域描述符 , N代表的是几维数组。例如:

int  [ ][ ] 其描述符为[[Ifloat[ ][ ] 其描述符为[[F

3.3方法描述符(方法签名)

将参数类型的域描述符按照申明顺序放入一对括号中后跟返回值类型的域描述符,规则如下: (参数的域描述符的叠加)返回

类型描述符。对于,没有返回值的,用V(表示void型)表示。举例如下:

将参数类型的域描述符按照申明顺序放入一对括号中后跟返回值类型的域描述符,规则如下: (参数的域描述符的叠加)返回

类型描述符。对于,没有返回值的,用V(表示void型)表示。举例如下:

Java层方法                                               JNI函数签名String test ( )                                              Ljava/lang/String;int f (int i, Object object)                            (ILjava/lang/Object;)Ivoid set (byte[ ] bytes)                                ([B)V

为什么会有方法签名这种东西呢?这是因为Java这边支持函数重载,即虽然参数不一样,但是方法名一样,那么在JNI层它们的方法名都会是一样的,那JNI也会犯迷糊了,得找哪个呢?
不过也正是因为其参数类型是不一样的,所以就出现了方法签名,利用方法签名和方法名来唯一确定一个JNI函数的调用。
既然方法签名是基于参数类型的不同而形成的,首先要知道Java各数据类型对应的签名是什么,也就是所谓的类型签名

对应于Java端的数据类型,我们也可以看一下下面的表: Java 类型 类型签名boolean Zbyte    Bchar    Cshort   Sint Ilong    Lfloat   Fdouble  D类   L全限定名;,比如String, 其签名为Ljava/lang/util/String;数组  [类型签名, 比如 [B

有方法 1):

public string addTail(String tail, int index)

其对应的签名如下:

(Ljava/util/String;I)Ljava/util/String;

方法 2):

public int addValue(int index, String value,int[] arr)

其对应的签名如下:

(ILjava/util/String;[I)I

相信通过这两个例子,大家也能够了解了方法签名是什么样的形式了吧,对于JNI这些奇形怪状的表示形式也有一定的了解了。

NdkDemo代码已上传至Github

如有不正支出,欢迎留言交流!
我的GitHub
我的CSDN
我的简书
开发笔记

原创粉丝点击