JNA(Java Native Access):建立在JNI之上的Java开源框架,SUN主导开发,用来调用C、C++代码,尤其是底层库文件(windows中叫dll文件,linux下是so【shared object】文件)。
JNI是Java调用原生函数的唯一机制,JNA就是建立在JNI之上,JNA简化了Java调用原生函数的过程。JNA提供了一个动态的C语言编写的转发器(实际上也是一个动态链接库,在Linux-i386中文件名是:libjnidispatch.so)可以自动实现Java与C之间的数据类型映射。从性能上会比JNI技术调用动态链接库要低。
由于项目中经常要用到java调用so库的情况,这里做一个简单的使用笔记留着回顾。
1、写一个简单的test.c文件:
#include<stdio.h> int add(int a, int b); int add(int a, int b) { int c = a + b; printf("Hello, this method is used to add two Integer."); return c; }
2、将.c文件编译为so动态链接库
[keysystem@localhost jnaTest]$ gcc -fpic -c test.c [keysystem@localhost jnaTest]$ gcc -shared -o libtest.so test.o [keysystem@localhost jnaTest]$ ll -rlt total 1140 -rw-rw-r--. 1 keysystem keysystem 162 Apr 21 15:17 test.c -rw-rw-r--. 1 keysystem keysystem 1146966 Apr 21 15:38 test.jar -rw-rw-r--. 1 keysystem keysystem 1616 Apr 21 15:46 test.o -rwxrwxr-x. 1 keysystem keysystem 5940 Apr 21 15:46 libtest.so [keysystem@localhost jnaTest]$
这样就会生成so库文件了。这里so库的命名要为libtest.so,而不能是test.so。因为JNA在找so
3、创建java project,编写Test.java
因为是使用JNA,所以要依赖jna.jar
jna.jar下载地址:http://central.maven.org/maven2/net/java/dev/jna/jna/4.5.1/jna-4.5.1.jar
将jar包引入到项目中
Test.java代码如下:
package jnaTestNew; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; public class Test { public interface CLibraryTest extends Library { //将so库放到/usr/lib64目录下 //注意名称要去掉lib前缀和.so的后缀 // CLibraryTest INSTANCE = (CLibraryTest) Native.loadLibrary("test", CLibraryTest.class); //将so库放在非系统目录下,以绝对路径的方式引用 CLibraryTest INSTANCE = (CLibraryTest) Native.loadLibrary("test", CLibraryTest.class, NativeLibrary.getInstance("/home/keysystem/jnaTest/libtest.so").getOptions()); int add(int a, int b); } public static void main(String[] args) { int a = 6; int b = 6; int c = CLibraryTest.INSTANCE.add(a, b); System.out.println("a:" + a); System.out.println("b:" + b); System.out.println("c为a+b的和:"); System.out.println("c:" + c); } }
其中重点关注so库放置的位置,可以是系统目录即/usr/lib64目录下(64位的操作系统和JDK);
也可以放置在任意可访问路径下,以绝对路径引用,使用方法参见上面的代码。
4、将java Project项目export导出jar包,如test.jar
将jar包放到Linux系统上执行java -jar test.jar
调用情况如下:
[keysystem@localhost jnaTest]$ ll -rlt total 1140 -rw-rw-r--. 1 keysystem keysystem 162 Apr 21 15:17 test.c -rw-rw-r--. 1 keysystem keysystem 1146966 Apr 21 15:38 test.jar -rw-rw-r--. 1 keysystem keysystem 1616 Apr 21 15:46 test.o -rwxrwxr-x. 1 keysystem keysystem 5940 Apr 21 15:46 libtest.so [keysystem@localhost jnaTest]$ /home/keysystem/jnaTest [keysystem@localhost jnaTest]$ java -jar test.jar a:6 b:6 c为a+b的和: c:12 Hello, this method is used to add two Integer.[keysystem@localhost jnaTest]$
使用过程中需要注意代码里的so库路径要与so库存放路径一致。