JNI皮假,是Java Native Interface的縮寫
· Java程序中的函數可以調用Native語言寫的函數,Native一般指的是C/C++編寫的函數。
· Native程序中的函數可以調用Java層的函數,也就是在C/C++程序中可以調用Java的函數摇锋。
java做的事
· 加載對應的JNI庫。
· 聲明由關鍵字native修飾的函數站超。
JNI做的事
. JNI層必須實現(xiàn)為動態(tài)庫的形式荸恕,這樣Java虛擬機才能加載它并調用它的函數。
. 注冊JNI函數--之意就是將Java層的native函數和JNI層對應的實現(xiàn)函數關聯(lián)起來
. 數據類型轉換
.JNIEnv通過調用CallVoidMethod死相,CallIntMethod等調用Java對象
一融求、注冊JNI函數
1、靜態(tài)注冊
· 先編寫Java代碼算撮,然后編譯生成.class文件生宛。
· 使用Java的工具程序javah县昂,如javah–o output packagename.classname ,這樣它會生成一個叫output.h 的JNI層頭文件陷舅。其中packagename.classname是Java代碼編譯后的class文件倒彰,而在生成的output.h文件里,聲明了對應的JNI層函數蔑赘,只要實現(xiàn)里面的函數即可狸驳。
關聯(lián)關系,其實就是保存JNI層函數的函數指針缩赛。以后再調用native_init函數時,直接使用這個函數指針就可以了撰糠,當然這項工作是由虛擬機完成的酥馍。
2、動態(tài)注冊
動態(tài)注冊的工作阅酪,只用兩個函數就能完成
.jclass clazz = (env)->FindClass(env, className);
. //調用JNIEnv的RegisterNatives函數旨袒,注冊關聯(lián)關系。
(env)->RegisterNatives(env, clazz, gMethods,numMethods);
當Java層通過System.loadLibrary加載完JNI動態(tài)庫后术辐,緊接著會查找該庫中一個叫JNI_OnLoad的函數砚尽,如果有,就調用它辉词,而動態(tài)注冊的工作就是在這里完成的必孤。
二、數據類型轉換
在Java中調用native函數傳遞的參數是Java數據類型瑞躺,那么這些參數類型到了JNI層會變成什么呢敷搪?
Java數據類型分為基本數據類型和引用數據類型兩種
三、JNIEnv介紹
JNIEnv實際上就是提供了一些JNI系統(tǒng)函數幢哨。通過這些函數可以做到:
· 調用Java的函數赡勘。
· 操作jobject對象等很多事情。
1捞镰、jfieldID 和jmethodID的介紹
在JNI規(guī)則中用jfieldID 和jmethodID 來表示Java類的成員變量和成員函數通過JNIEnv的下面兩個函數可以得到:
jfieldID GetFieldID(jclass clazz,const char*name, const char sig);
jmethodID GetMethodID(jclass clazz, const charname,const char *sig);
2闸与、使用jfieldID和jmethodID
JNIEnv通過調用CallVoidMethod,CallIntMethod岸售、CallStatic等再把jobject践樱、jMethodID和對應參數傳進去,JNI層就能夠調用Java對象的函數了