一.JNI?的開(kāi)發(fā)流程
JNI 開(kāi)發(fā)
步驟:
1.編寫(xiě)native 方法
2.javah 命令汰聋,生成.h 文件
java_類的全名_方法名
或者自己手寫(xiě)
3.復(fù)制.h 頭文件到cpp 工程
4.復(fù)制jni.h 和jni_md.h
5.實(shí)現(xiàn).h 頭文件中的聲明函數(shù)
6.生成一個(gè)dll 動(dòng)態(tài)庫(kù)
7.在java中加載動(dòng)態(tài)庫(kù)
8.觸發(fā)native函數(shù)
二.JNI的數(shù)據(jù)類型
在JNI的世界里也存在類似的數(shù)據(jù)類型精偿,與Java比較起來(lái),其范圍更具嚴(yán)格性山宾,如下:
1、primitive types ----基本數(shù)據(jù)類型芭逝,如:int塌碌、 float 渊胸、char等基本類型
2旬盯、reference types----引用類型,如:類、實(shí)例胖翰、數(shù)組接剩。
特別需要注意:數(shù)組------ 不管是對(duì)象數(shù)組還是基本類型數(shù)組,都作為reference types存在萨咳。
1懊缺、primitive types(基本數(shù)據(jù)類型)映射參見(jiàn)下表:
這些基本數(shù)據(jù)類型都是可以在Native層直接使用的 。
2培他、reference types(引用數(shù)據(jù)類型)映射參見(jiàn)下表
注意:
1鹃两、引用數(shù)據(jù)類型則不能直接使用,需要根據(jù)JNI函數(shù)進(jìn)行相應(yīng)的轉(zhuǎn)換后舀凛,才能使用
2俊扳、多維數(shù)組(包括二維數(shù)組)都是引用類型,需要使用jobjectArray類型存取其值 猛遍;
例如:二維整型數(shù)組就是指向一位數(shù)組的數(shù)組馋记,其聲明使用方式如下:
//獲得一維數(shù)組?的類引用,即jintArray類型
jclass?intArrayClass?=?env->FindClass("[I");
//構(gòu)造一個(gè)指向jintArray類一維數(shù)組的對(duì)象數(shù)組懊烤,該對(duì)象數(shù)組初始大小為dimion
jobjectArray?obejctIntArray??=??env->NewObjectArray(dimion?,intArrayClass?,?NULL);
...//具體操作
另外梯醒,關(guān)于引用類型的一個(gè)繼承關(guān)系如下,我們可以對(duì)具有父子關(guān)系的類型進(jìn)行轉(zhuǎn)換:
類描述符是類的完整名稱(包名+類名),將原來(lái)的 . 分隔符換成 / 分隔符腌紧。
例如:在java代碼中的java.lang.String類的類描述符就是java/lang/String
其實(shí)茸习,在實(shí)踐中,我發(fā)現(xiàn)可以直接用該類型的域描述符取代寄啼,也是可以成功的逮光。
例如:jclass intArrCls = env->FindClass("java/lang/String")
等同于jclass intArrCls = env->FindClass("Ljava/lang/String;")
數(shù)組類型的描述符則為,則為: ?[ + 其類型的域描述符 ? ? ? ?(后文說(shuō)明)
例如:
int [ ] ? ? 其描述符為[I
float [ ] ? 其描述符為[F
String [ ] ?其描述符為[Ljava/lang/String;
1墩划、基本類型的描述符已經(jīng)被定義好了涕刚,如下表所示:
2、引用類型的描述符
一般引用類型則為 L + 該類型類描述符 + ;(注意乙帮,這兒的分號(hào)“杜漠;”只得是JNI的一部分,而不是我們漢語(yǔ)中的分段察净,下同)
例如:String類型的域描述符為 Ljava/lang/String;
對(duì)于數(shù)組驾茴,其為 : ?[ + 其類型的域描述符 + ;
int[ ] ? ? 其描述符為[I
float[ ] ? 其描述符為[F
String[ ] ?其描述符為[Ljava/lang/String;
Object[ ]類型的域描述符為[Ljava/lang/Object;
多維數(shù)組則是 n個(gè)[ +該類型的域描述符 , N代表的是幾維數(shù)組。例如:
int ?[ ][ ] 其描述符為[[I
float[ ][ ] 其描述符為[[F
將參數(shù)類型的域描述符按照申明順序放入一對(duì)括號(hào)中后跟返回值類型的域描述符氢卡,規(guī)則如下: (參數(shù)的域描述符的疊加)返回
類型描述符锈至。對(duì)于,沒(méi)有返回值的译秦,用V(表示void型)表示峡捡。舉例如下:
Java層方法 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? JNI函數(shù)簽名
String test ( ) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Ljava/lang/String;
int f (int i, Object object) ? ? ? ? ? ? ? ? ? ? ? ? ? ?(ILjava/lang/Object;)I
void set (byte[ ] bytes) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?([B)V
在編程時(shí)击碗,如果是利用javah工具的話,這些都不需要我們手動(dòng)編寫(xiě)對(duì)應(yīng)的類型轉(zhuǎn)換们拙,如果不能用javah工具稍途,就只能手動(dòng)的
進(jìn)行類型轉(zhuǎn)換了。