JNI学习
练习java文件
| |
- 通过
System.loadLibrary("[库名称]")加载库。 - 通过
native声明函数,表示这是个本地函数,需要通过jni来调用其他语言中的函数。
生成头文件
java10以下:
| |
java10及以上:
| |
以上命令会在相对地址include目录下生成com_vee_test_HelloJNI.h头文件:
| |
其中最主要的就是函数JNIEXPORT void JNICALL Java_HelloJNI_sayHello (JNIEnv *, jobject);,参数解释如下:
- JNIEnv*:JNI运行环境的指针
- jobject: 调用对象,指代java中的this对象。
编译出库
linux
| |
- -I 包含编译JNI必要的头文件
- -fPIC 编译成与位置无关的独立代码
- -shared 编译成动态库
- -o 指定编译后动态库生成的路径和文件名(一般用libXXX.so命名),这里我们把so放在libs目录下。
运行
| |
-Djava.library.path是指明java的库路径,如果不加这个选项,则java默认会去系统属性指定的目录下查找动态库文件,找不到会报错:
| |
可以看到,java会默认从这两个目录中找:
- /usr/lib
- /usr/lib64
数据类型
基本数据类型
| java | jni | c/c++ | description |
|---|---|---|---|
| boolean | jboolean | unsigned char | unsigned 8 bits |
| byte | jbyte | signed char | signed 8 bits |
| char | jchar | unsigned short | unsigned 16 bits |
| short | jshort | signed short | signed 16 bits |
| int | jint | signed int | signed 64 bits |
| long | jlong | signed long | signed 64 bits |
| float | jfloat | float | 32 bits |
| double | jdouble | double | 64bits |
注意:这些数据类型是可以在JNI中直接时使用的,不需转换。
引用数据类型
| java | jni |
|---|---|
| java.lang.Object | jobject |
| java.lang.String | jstring |
| java.lang.Class | jclass |
| Object[] | jobjectArray |
| boolean[] | jbooleanArray |
| byte[] | jbyteArray |
| char[] | jcharArray |
| short[] | jshortArray |
| int[] | jintArray |
| long[] | jlongArray |
| float[] | jfloatArray |
| double[] | jdoubleArray |
| java.lang.Throwable | jthrowable |
| void | void |
引用类型不能直接使用,需要经过JNI函数转换才能使用:
| |
JNI中所有的array类型,都继承自jarray类型
类描述符
域描述符
JNIENV
JNIEnv,英文全称是Java Native Interface Environment,用咋中国话来说就是Java本地接口环境。
在JNI中,通过native方法编译出的.h文件中对应的函数声明,第一个参数永远是JNIEnv的指针。
JNI中提供了一系列的方式供我们使用:
| 函数 | 功能 |
|---|---|
| FindClass | 加载本地定义的类型 |
| GetObjectClass | 获取对象的类型 |
| NewGlobalRef | 创建obj参数所引用对象的新全局引用 |
| NewObject | 构造新的java对象 |
| NewString | 利用Unicode字符数组构造新的java.lang.String对象 |
| New | 创建类型为Type的数组对象 |
| Get | 获取类型为Type的字段 |
| Set | 设置类型为Type的字段 |
| GetStatic | 获取类型为Type的static的字段的值 |
| SetStatic | 设置类型为Type的static的字段的值 |
| Call | 调用返回类型为Type的方法 |
| CallStatic | 调用返回值类型为Type的static方法 |