1. 程式人生 > >Java呼叫庫檔案(JNI)(android對此有所改變)

Java呼叫庫檔案(JNI)(android對此有所改變)

1.準備java 程式 testdll.java,內容為: public class testdll {  static {     System.loadLibrary("goodluck"); //載入庫名,庫的副檔名字究竟是DLL還是SO,由系統自己判斷。 }  //還需對將要呼叫的方法做本地宣告,關鍵字為native。且只需要宣告,而不需要具體實現 public native static int get();  public native static void set(int i);  public static void main(String[] args) {     testdll test = new testdll();     test.set(10);     System.out.println(test.get());  }  } 然後編譯該JAVA程式檔案,生成CLASS,再用JAVAH命令,JNI就會生成C/C++的標頭檔案。 用javac testdll.java編譯它,會生成testdll.class。  再用javah testdll,則會在當前目錄下生成testdll.h檔案,內容如下: #include  #ifndef _Included_testdll  #define _Included_testdll  #ifdef __cplusplus  extern "C" {  #endif  JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);  JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);  #ifdef __cplusplus  }  #endif  #endif 在具體實現的時候,我們只關心兩個函式原型  JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass); 和  JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint); 這裡JNIEXPORT和JNICALL都是JNI的關鍵字,函式的名稱是JAVA_再加上java程式的package路徑再加函式名組成的。 下面我們用testdll.cpp檔案具體實現這兩個函式; #include "testdll.h"  int i = 0;  JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)  {  return i;  }  JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j)  {  i = j;  } 編譯連線成庫檔案,本例是在WINDOWS下做的,生成的是DLL檔案,名字為goodluck.dll。把goodluck.dll拷貝到testdll.class的目錄下(或者加入環境變數中),java testdll執行它。 對於最重要得引數傳遞,字長不一樣,因此,需要轉換。比如傳遞字串,java檔案中引數為byte[] param,c檔案中為jbyteArray,轉換可以如下進行: jsize theArrayLengthJ = (*env)->GetArrayLength(env,param);        //得到本地字長 jbyte * arrayBody = (*env)->GetByteArrayElements(env,param,0);//得到本地元素 char* str=(char *)arrayBody; main中: byte[] temp = {0};            //字串末尾補0 String str= "早上好"; byte[] bb= str.getBytes("gbk"); byte[] lastBB = new byte[str.length + temp.length];   //得到最終要傳遞得引數 就是在傳遞位元組陣列到C程式中時,最後的結尾一定要以0結束。