Java的JNI的簡單應用(對接C或者C++)
1.什麼是JNI
JNI是Java Native Interface的縮寫,通過使用 Java本地接口書寫程式,可以確定代碼在不同的平台上友善移植。 [1] 從Java1.1開始,JNI标準成為java平台的一部分,它允許Java代碼和其他語言寫的代碼進行互動。JNI一開始是為了本地已編譯語言,尤其是C和C++而設計的,但是它并不妨礙你使用其他程式設計語言,隻要調用約定受支援就可以了。使用java與本地已編譯的代碼互動,通常會喪失平台可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的。例如,使用一些舊的庫,與硬體、作業系統進行互動,或者為了提高程式的性能。JNI标準至少要保證本地代碼能工作在任何Java 虛拟機環境。
以上内容來至百度百科,簡單來說就是java調用其它語言的一個機制。
至于為什麼要用JNI,請自行Google或者百度
2.調試環境
Jdk1.8 ;Eclipse;Visual Stdio 2017;
調試環境也可以和我不一樣,但是大體流程都是差不多的,自己注意一下細節就可以了
3.準備過程
1.首先在eclipse中建立HJ.java.然後聲明幾個native方法。
代碼如下:
public class HJ {
public native int intMethod(int n);
public native boolean booleanMethod(boolean bool);
public native String stringMethod(String text);
public native int intArrayMethod(int[] intArray);
}
以上代碼用java定義了四個native方法,然後準備使用C/C++來實作這四個方法。
接下來使用java指令生成native方法的頭檔案:
javac HJ.java -h ./
頭檔案,在C/C++中一般是用于定義方法和函數的一個檔案。在編譯的時候頭檔案相當于被寫到引用頭檔案的C檔案的前面。
新生成的.h的内容(以下代碼是執行java指令後自動生成的 ):
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class zhp_jni_HJ */
#ifndef _Included_zhp_jni_HJ
#define _Included_zhp_jni_HJ
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: zhp_jni_HJ
* Method: intMethod
* Signature: (I)I
* 簡要解釋:這裡的jint相當于是java中的int方法的一個标記
*/
JNIEXPORT jint JNICALL Java_zhp_jni_HJ_intMethod
(JNIEnv *, jobject, jint);
/*
* Class: zhp_jni_HJ
* Method: booleanMethod
* Signature: (Z)Z
*/
JNIEXPORT jboolean JNICALL Java_zhp_jni_HJ_booleanMethod
(JNIEnv *, jobject, jboolean);
/*
* Class: zhp_jni_HJ
* Method: stringMethod
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_zhp_jni_HJ_stringMethod
(JNIEnv *, jobject, jstring);
/*
* Class: zhp_jni_HJ
* Method: intArrayMethod
* Signature: ([I)I
*/
JNIEXPORT jint JNICALL Java_zhp_jni_HJ_intArrayMethod
(JNIEnv *, jobject, jintArray);
#ifdef __cplusplus
}
#endif
#endif
接下來在VisualStdio中建立一個C/C++的dll項目。然後在将剛剛生成的.h頭檔案複制到項目的檔案目錄中。并将java安裝目下的jdk下的include目錄裡面的内容添加到新加C/C++的dll項目的引用中去。在項目中建立一個.cpp檔案。并include之前的.h檔案。對.h檔案中的方法進行實作。(這裡注意一下,我用的visual stdio 2017在引入jdk目錄下的include檔案夾後,編輯器提示報錯,然後跟蹤了一下代碼發現是java自帶的include檔案夾下的一個.h檔案中的include路徑有問題,這個具體視個人環境而定,如有遇到莫名其妙的報錯,可以檢視一下。自己手動修改一下include就可以了)
大緻代碼如下:
#include<string.h>
#include"zhp_jni_HJ.h"
JNIEXPORT jint JNICALL Java_zhp_jni_HJ_intMethod
(JNIEnv *env, jobject obj, jint num)
{
return num * num;
}
JNIEXPORT jboolean JNICALL Java_zhp_jni_HJ_booleanMethod
(JNIEnv *env, jobject obj, jboolean boolean)
{
return !boolean;
}
JNIEXPORT jstring JNICALL Java_zhp_jni_HJ_stringMethod
(JNIEnv *env, jobject obj, jstring string)
{
return NULL;
}
JNIEXPORT jint JNICALL Java_zhp_jni_HJ_intArrayMethod
(JNIEnv *env, jobject obj, jintArray array)
{
int i, sum = 0;
return sum;
}
這裡因為是學習測試的代碼是以比較簡單,更複雜的邏輯順着這個思路來應該能解決。
最後編譯生成dll檔案,移到java能讀到的目錄(這裡的目錄是“java.library.path”目錄)。可以用
System.getProperty("java.library.path")
自己的這個屬性的目錄有哪些,然後把生成好的dll移動到其中一個目錄下即可。
最後使用:
System.loadLibrary("your_dll_name")
加載後即可調用相應的方法。
4.運作結果
本人才疏學淺,如有錯誤,歡迎指正,謝謝!
(轉載請注明來源)