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庫存放路徑一致。