上一篇 JNI与NDK开发(三)—— Java调用C的推荐方法 中我说我们使用了,一种叫做 Signature 的描述符。下面,详细说一下它的作用和使用规则。
Signature作用?
Java 与C/C++相互调用时,表示函数参数和返回值的描述符。
为什么需要Signature?
Java 与C/C++之所以能相互调用,是因为JavaVM中建立着一张映射表。这张映射表,包含Java方法和C/C++函数指针的一一对应的数据信息,可以用有key / value的Map表进行类比理解。
key就是一个唯一的字符串,value就是函数指针。通过key字符串就能找到对应的value的函数指针,最终可以让JavaVM实现Java 与C/C++相互调用。
通常生成key字符串的方式,就是将函数名和参数结合起来进行生成,这样获得的字符串才具有唯一性(同一个class中,方法名相同,但是参数不能完全相同)。结合以上知识和Signature作用,就可以理解为什么需要Signature。Signature表示了函数参数和返回值类型,结合native方法名,就可以生成唯一的key。
下面是Signature的使用,这段代码包含了native的方法名:
{"jniRecommend","()Ljava/lang/String;",(void*)my_jni_recommend}
Signature语法规则:
1、输入参数放在()里面,输出参数放在()外边,且在()的右边;
2、多个参数之间顺序存放,且用“ ;”进行分隔;
3、Java原始类型的Signature;
Java中的类型 | Signature符号 |
---|---|
boolean | Z |
byte | B |
char | C |
short | S |
int | I |
long | J |
float | F |
double | D |
注:除了 boolean —— Z ,其他都是首字母。
4、Java对象参数 “L包路径/类名”,L表示这个参数是一个类,后面跟着类的路径。
例子1:
([Lcom/test/Teacher;[I;)[Lcom/test/Student;
以上Signature表示:
1、第一个输入参数(看括号内部) 是一个类(类用L表示),这个类的路径是com/test/Teacher。
2、第二个输入参数,是一个int数组;
3、输出参数是一个类(类用L表示),这个类的路径是com/test/Student。
使用Java表示如下:
public Student[] Xxx (Teacher[] xx,int[] x){}
标识符这种东西就是这样,只能按着规则读写。为啥这样写?不用问为啥,这是人家规定好的。这个就跟“天王盖地虎”,为啥下一句是“宝塔镇河妖”?!
前面都是在讲,Java层调用C/C++层的代码。后面一篇会介绍C/C++代用Java的方法。