- 基本数据类型的转换
Java|Native| Signature(函数签名)
--|--|--|
byte| jbyte| B
char| jchar| C
double| jdouble| D
float| jfloat| F
int| jint| I
short |jshort| S
long |jlong| J
boolean |jboolean| Z
void |void| V
从上表可以可看出,基本数据类型转换,除了void,其他的数据类型只需要在前面加上“j”就可以了。第三列的Signature 代表签名格式,后文会介绍它。接着来看引用数据类型的转换。
- 引用数据类型的转换
Java | Native | Signature(函数签名) |
---|---|---|
所有对象 | jobject | L+classname +; |
Class | jclass | Ljava/lang/Class; |
String | jstring | Ljava/lang/String; |
Throwable | jthrowable | Ljava/lang/Throwable; |
Object[] | jobjectArray | [L+classname +; |
byte[] | jbyteArray | [B |
char[] | jcharArray | [C |
double[] | jdoubleArray | [D |
float[] | jfloatArray | [F |
int[] | jintArray | [I |
short[] | jshortArray | [S |
long[] | jlongArray | [J |
boolean[] | jbooleanArray | [Z |
从上表可一看出,数组的JNI层数据类型需要以“Array”结尾,签名格式的开头都会有“[”。除了数组以外,其他的引用数据类型的签名格式都会以“;”结尾。
另外,引用数据类型还具有继承关系,如下所示

- 方法签名
(参数签名格式...)返回值签名格式
拿sayHello方法举例,他在Java中是如下定义的:
private native final void sayHello(Object mediarecorder_this,
String clientName, String opPackageName) throws IllegalStateException;
它在JNI中的方法签名为:
(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V
查询上述表知
Object mediarecorder_this的函数签名Ljava/lang/Object
String clientName的函数签名Ljava/lang/String;
String opPackageName的函数签名Ljava/lang/String;
返回值类型void 的签名为“V”,组合起来就是上面的方法签名。
使用命令查看函数签名
1、对java文件编译 生成class文件,执行如下命令

接着执行如下图命令,便可看到函数签名
javap -s -p xxxxx
其中s 表示输出内部类型签名,p表示打印出所有的方法和成员(默认打印public成员),最终会在cmd中的打印结果如下:

使用Javah 生成h 头文件在(在包名外的java目录)

JNIEnv
JNIEnv 是一个指向全部JNI方法的指针,该指针只在创建它的线程有效,不能跨线程传递,因此,不同线程的JNIEnv是彼此独立的,JNIEnv的主要作用有两点:
1.调用Java的方法。
2.操作Java(获取Java中的变量和对象等等)。
jfieldID和jmethodID
在JNI中用jfieldID和jmethodID来代表Java类中的成员变量和方法,可以通过JNIEnv的下面两个方法来分别得到:
jfieldID GetFieldID(jclass clazz,const char *name,const char *sig);
jmethodID GetFieldID(jclass clazz,const char *name,const char *sig);
其中,jclass代表Java类,name代表成员方法或者成员变量的名字,sig为这个方法和变量的签名
例子
jmethodID methodID = (*env)->GetStaticMethodID(env, clzz, "staticmethod",
"(Ljava/lang/String;)V");
或取Java里面的staticmethod方法,有一个参数且无返回值
网友评论