天天看點

Java調用C/C++語言的方法Java的JNI的簡單應用(對接C或者C++)

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 ./

Java調用C/C++語言的方法Java的JNI的簡單應用(對接C或者C++)

頭檔案,在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.運作結果

Java調用C/C++語言的方法Java的JNI的簡單應用(對接C或者C++)

本人才疏學淺,如有錯誤,歡迎指正,謝謝!

(轉載請注明來源)