Java 呼叫本地Native介面指引
阿新 • • 發佈:2019-01-28
Java本地介面允許java使用者用程式碼與其他語言介面互動的一種方法,native方法允許java語言呼叫其他語言,增加了程式碼的靈活性
1、Java本地介面的好處
通過使用Java介面,可以增加程式碼的靈活性與重用性,假如我們想在java裡用一段C語言的程式碼實現的功能,我們不用全部重寫所有C語言程式碼,而是可以加一個C語言介面類,與java互動即可。 通過java介面,還可以提升java程式的效能瓶頸,我們知道,java在執行的時候由於需要執行在jvm上,因此效率會有所下降,這也是為了跨平臺性做了一個折中的辦法,通過jni,我們可以將一些程式碼放在native程式碼中,通常native程式碼的速度比java程式碼快很多,因此可以提升java程式的效能。2、Java本地方法的開發過程
public class Hello { public native void sayHi(); //1 static { System.loadLibrary("hello"); } //2 public static void main (String[] args) { Hello hello = new Hello(); System.out.println("I will Print:"); hello.sayHi();//3 } }
其中,第一步建立一個native的sayHi方法,方法的實現並未實現,而是由下面的C語言來實現。 第二步載入C語言庫,在windows下,庫名為hello.dll,在Linux下,庫名為libhello.so,在macos系統下庫名為libhello.jnilib 第三步在main方法裡面呼叫我們定義的native方法,來驗證我們的方法是否成功執行。 其次,通過javac工具編譯這個類:
$ javac Hello.java
如果是有包的話需要加上包路徑名。 然後,用javah工具建立native的.h標頭檔案,這個檔案為自動生成
$ javah -jni Hello
建立好之後,我們的資料夾中就多了個Hello.h標頭檔案:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Hello */ #ifndef _Included_Hello #define _Included_Hello #ifdef __cplusplus extern "C" { #endif /* * Class: Hello * Method: sayHi * Signature: ()V */ JNIEXPORT void JNICALL Java_Hello_sayHi (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
這個檔案裡定義了我們需要實現的函式原型:
JNIEXPORT void JNICALL Java_Hello_sayHi
(JNIEnv *, jobject);
然後我們需要實現具體的定義,建立一個hello.c檔案:
#include<stdio.h>
#include"Hello.h"
JNIEXPORT void JNICALL
Java_Hello_sayHi(JNIEnv *env, jobject obj) {
printf("Hello World\n");
}
在實現中,我們需要include我們剛才自動建立好的.h檔案,並且實現它定義的函式。 然後我們生成.so庫檔案:
$ gcc -o libhello.so -fPIC -lc -shared -I /usr/lib/jvm/java/include -I /usr/lib/jvm/java/include/linux hello.c
-o為輸出檔名,不能隨意更改,要以lib+庫名(就是java程式碼裡loadLibrary裡的字串)+.so命名
-I 由於需要jni.h和其他的一些標頭檔案,需要加上依賴的標頭檔案路徑
然後我們需要把當前檔案目錄加入庫檔案路徑中:
$ export LD_LIBRARY_PATH=.
ok,至此已經全部完成操作,最後我們java Hello就可以執行程式碼了。