JNI 之Java和c/c++互動,提升Java變成效率
阿新 • • 發佈:2018-11-05
JNI 主要是java和c++相互呼叫,java可以把效率低,耗時操作比較嚴重的邏輯放在c++裡面。可以大大提升效率和節省資源。
下面是java呼叫的windows下的 c++的dll動態庫,還有一種是標準c的linux的so動態庫。工程結構圖如下:
第一步:編寫Java程式碼:
public class JniTest {
public native static String getString();
//【坑1】注意千萬不要寫成 public static native String getString()
//這樣編譯的dll動態庫用不了,老是報莫名其妙的錯
public static void main(String[] args) {
String result=getString();
System.out.println("test=java jni ="+result);
}
//載入動態庫
static {
//正確匯入方式
System.loadLibrary("JniDemo");
}
}
第二步:給java 呼叫類生成標頭檔案
先複製工程目錄src的路徑
在開啟cmd 利用javah生成標頭檔案
//【坑2】java所在的類不能是GBK編碼,不然報錯
//【坑3】javah 後面是跟著java類的copy qualifed name
第三步:在visual studio 2013上新建空專案
a.將javah生成的標頭檔案複製到vs工程目錄下面,如下圖所示:
b.vs引入標頭檔案,如下圖找到vs工程目錄下的剛制過來的標頭檔案,點選確定
c.vs引入剛才的標頭檔案錯誤消除,如下圖所示:
然後將jdk的兩個.h標頭檔案複製到vs工程目錄下,並引入
C:\Program Files\Java\jdk1.8.0_152\include\jni.h
C:\Program Files\Java\jdk1.8.0_152\include\win32\jni_md.h
引入之後錯誤立馬消失。
//開啟javah生成java標頭檔案的裡面內容
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jni_test_JniTest
* Method: getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_jni_1test_JniTest_getString
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
d.在vs工程原始檔中新建JniTest.c檔案,空白檔案,並編寫程式碼
#include "jni_test_JniTest.h"
//【坑4】方法和#include要有空行,不然報錯
//下面這個方法是javah標頭檔案中直接複製過來
JNIEXPORT jstring JNICALL Java_jni_1test_JniTest_getString
(JNIEnv *Env, jclass jclass){
//c或者c++實現函式
char *string = "what the fuck";
return (*Env)->NewStringUTF(Env, string);
};
第四步:vs生成dll動態庫,設定步驟如下圖所示:
最後點選vs的-》生成-》生成解決方案
第五步:將生成的dll動態庫複製拷貝到java工程的更目錄下面
第六步:執行java工程測試結果如下:(eclipse空間是GBK的,有亂碼)
總結:總體來說java的jni互動流程還是有點複雜的,很容易出錯。