JNI定义
JNI是Java Native Interface的缩写,通过使用Java本地接口书写程序,可以确保代码在不同的平台上方便移植。
很多底层功能或者硬件及驱动方面的功能是C/C++ 完成的, 想要和这些程序打交道的媒介就是JNI。
所需环境
1. Ubuntu 系统 (本文系统 16.04 LTS)
2. JDK (请自行安装)
JNI实现步骤
1. 编写java代码 (HelloJNI.java)
1 | class HelloJNI{ |
2. 编译java代码
1 | losedeer@xr:~/JNI_TEST$ javac HelloJNI.java |
3. 编译映射C与Java之间的头文件
Java提供了 javah 命令 , 用来生成包含函数原型的C/C++的头文件. (可以理解为建立java 和 C 之间的连接规则!)
1 | losedeer@xr:~/JNI_TEST$ javah HelloJNI |
执行上述命令后,会生成一个.h 的头文件.(HelloJNI.h)
1 | /* DO NOT EDIT THIS FILE - it is machine generated */ |
4.根据头文件来实现C程序
根据头文件规则:
编写C程序:(hellojni.c)
1 |
|
5. 制作C的静态库
Tips:
1. /usr/lib/jvm/java-1.8.0-openjdk-amd64/include 的片段这个是你的JDK 安装的路径!
2. 库文件命名规则!!! (Ubuntu 下为 libxxxx.so 文件 ! Windows 为 xxxx.dll 文件!)(xxxx为C的文件名)
1 | gcc -shared -I /usr/lib/jvm/java-1.8.0-openjdk-amd64/include -I /usr/lib/jvm/java-1.8.0-openjdk-amd64/include/linux hellojni.c -o libhellojni.so |
可以看到目录下生成了 libhellojni.so 文件
6. 运行Java程序(即可看见在C中实现的方法,可在JAVA中得到实现)
实现过程中 error 解决
第5步中:
若出现一下报错:
/usr/bin/ld: /tmp/ccC9m80Y.o: relocation R_X86_64_32 against `.rodata’ can not be used when making a shared object; recompile with -fPIC /tmp/ccC9m80Y.o: 无法添加符号: 错误的值
解决方法:
请第5步的命令之后添加 -fPIC 即:
1 | gcc -shared -I /usr/lib/jvm/java-1.8.0-openjdk-amd64/include -I /usr/lib/jvm/java-1.8.0-openjdk-amd64/include/linux hellojni.c -o libhellojni.so -fPIC |
第6步中:
Exception in thread “main” java.lang.UnsatisfiedLinkError: no hellojni in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at HelloJNI.
解决方法
1. 在目录下编写输出默认读取库函数的路径:(例如 Test.java)
1 |
|
2. 运行看看默认的库函数路径
可以看到我的库文件默认地址是:
/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib (这里有三个…… )
可以看到有三个地址,请自行查看你那个地址时存在的!!!!!!!!!!!!(本人只有 /usr/lib/ 是存在的)
接下来把生成的 libhellojni.so 文件复制过去
1 | losedeer@xr:~/JNI_TEST$ sudo cp libhellojni.so /usr/lib/ |