JNI即Java Native Interface,可以实现Java与其他语言的通信。
这里连接C++,思路为Java中函数声明为native,然后编译出 .h 文件,cpp文件实现 .h 中声明的函数。把cpp编译成 .o 然后编译成 .so,最后在Java中指定 .so 的位置。
首先在Java中声明native函数。
目录树为
接下来编译生成头文件
在命令行src目录下,jni为包名,JNI_test是类名
ooc@ooc-X550VC:~/workspace/JNI_test/src$ javah -jni jni.JNI_test
编译生成了 jni_JNI_test.h
新建 .c 或 .cpp文件,包括 #include "jni_JNI_test.h"头文件。
并实现此头文件中声明的函数,文件名及参数需和头文件中一致!(开始这里掉坑里了)
接下来就是编译c文件,先生成 .o 文件
ooc@ooc-X550VC:~/workspace/JNI_test/src$ g++ -I /usr/lib/jvm/java-7-openjdk-amd64/include/linux/ -I /usr/lib/jvm/java-7-openjdk-amd64/include/ -fPIC -c jni.c
ooc@ooc-X550VC:~/workspace/JNI_test/src$ ls
jni jni.c jni_JNI_test.h jni.o // 生成jni.o
- I : 表示增加头文件的搜索路径. (大写的i,开始还以为是小写的L)
<java_path>/include 是jni.h头文件所在的路径
<java_path>/include/linux 是jni_md.h所在的路径
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真 正代码段共享的目的。
接下来生成 .so 文件。
ooc@ooc-X550VC:~/workspace/JNI_test/src$ g++ -shared jni.o -o libgoodluck.so
ooc@ooc-X550VC:~/workspace/JNI_test/src$ ls
jni jni.c jni_JNI_test.h jni.o libgoodluck.so // 生成 libgoodluck.so
其中 .so 文件必须以lib开头。
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
最后把.so文件装载进库文件。System.load("/xxx/xxx/xxx/libxx.so"); //参数为绝对路径
输出:
注意:
JNI 中一个C文件可以看成一个单独的C程序。
即用JNI调用一个函数给C全局变量赋值,后用另一JNI接口可继续访问这个全局变量的值。
同一类的不同对象共享一个C程序,多线程下也可正常使用。