这里简单介绍一下JNI的语法
初识第一面
HelloJNI.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
HelloJNI.h/.c
1 2 3 4 | |
需要注意的有:
- 函数命名约定
Java_{package_and_classname}_{function_name}(JNI arguments) - JNIEnv*: 对于JNI环境的引用, 通过这个入口可以进行jni函数
- jobject: 对于this对象的引用
JNI基础
JNI在native系统中定义了下面这些JNI数据类型,来对应Java的类型。
- Java基本类型:jint,jbyte,jshort,jlong,jfloat,jdouble,jchar,jboolean对应Java的int,byte,short,long,float,double,char,boolean
- Java应用类型:jobject对应java.lang.Object。同时还有一下子类型
- jclass -> java.lang.Class
- jstring -> java.lang.String
- jthrowable -> java.lang.Throwable
- jarray -> Java Array。也就是jintArray, jbyteArray, jshortArray, jlongArray, jfloatArray, jdoubleArray, jcharArray, jbooleanArray, jobjectArray.
由于native的函数都是接受JNI类型参数,返回JNI类型参数,所以一般情况下我们需要这样做:
- 把JNI的参数转换或者拷贝成C可以操作的类型,如jintArray到int[]
- 使用C类型参数完成计算
- 把结果转换或者拷贝成JNI类型并返回
JNI环境提供了大量的这些转换工作的工具可以帮助大家完成
在Java和Nativie之间传递参数
基础类型
1 2 3 4 5 6 7 8 9 10 11 12 | |
String
JNI环境提供了函数可以进行很方便的转换
- jstring -> char* :
const char* GetStringUTFChars(JNIEnv*, jstring, jboolean*). - char* -> jstring :
jstring NewStringUTF(JNIEnv*, char*).
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
primitive数组
- jintArray -> jint[],
jint* GetIntArrayElements(JNIEnv *env, jintArray a, jboolean *iscopy). - jint[] -> jintArray, 首先分配内存
jintArray NewIntArray(JNIEnv *env, jsize len), 然后填充void SetIntArrayRegion(JNIEnv *env, jintArray a, jsize start, jsize len, const jint *buf)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
访问对象变量并且调用Java方法
访问实例对象
- GetObjectID
- GetFieldID
- GetInt
- SetFieldID
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
访问静态变量
- GetStaticFieldID
- GetStatic
Field - SetStatic
Field
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
访问方法和静态方法
- GetMethodID
- Call
Method - GetStaticMethodID
- CallStatic
Method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
创建java对象和对象数组
创建java对象
- FindClass
- NewObject
- AllocObject
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
创建java数组
- NewObjectArray
- GetObjectArrayElement
- setObjectArrayElement
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | |
本地和全局变量
任何类似FindClass(), GetMethodID(), GetFieldID()返回的引用是一个本地引用。
想要使用全局引用的话,需要使用NewGlobalRef(),DeleteGlobalRef()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |