1. 程式人生 > >JNI 之Java和c/c++互動,提升Java變成效率

JNI 之Java和c/c++互動,提升Java變成效率

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互動流程還是有點複雜的,很容易出錯。