今后的四篇文章,我們將從頭談?wù)揓ava的調(diào)用C++的JNI,以便大家開發(fā)出一些功能較強(qiáng)大些的Android應(yīng)用。如有疑問,請(qǐng)直接點(diǎn)擊頁面上的在線客服咨詢安博中程嵌入式專家。
1.有關(guān)JNI的類型方法表示,基本上C層面的類型均是j+java過去的類型,比如字符串在JNI的c層面為jstring而Java為String,對(duì)于布爾類型boolean則為jboolean對(duì)應(yīng)Java中的boolean。
2. 有關(guān)Java類的表示在JNI中對(duì)應(yīng)關(guān)系如下
long cwjInfo (int nAge, String sName, int[] arrSalary);
我們可以表示為 "(ILjava/lang/String;[I)J"我們?nèi)コp引號(hào),第一個(gè)(表示一個(gè)參數(shù)類型,接下來的I表示第一個(gè)參數(shù)為int整形,L代表是一個(gè)類class,這里為java/lang/String這個(gè)類,接下來是[代表是一個(gè)數(shù)組,后面的I代表一個(gè)整形的數(shù)組,而)后面的J代表返回類型,在JNI中J代表long長整形,相關(guān)的對(duì)應(yīng)關(guān)系如下:
V void
Z boolean
B byte
C char
S short
I int
J long
F float
D double
L fully qualified class
[ array type[]
( arg-types
3.Java層傳入的String不能在JNI中直接轉(zhuǎn)化為jstring,因?yàn)镴ava的內(nèi)部編碼為unicode,中英文的字符都是每個(gè)占兩個(gè)字節(jié),而jni中我們需要使用utf-8來表示,utf-8比較特殊中英文是不等長的,比如英文等符號(hào)的ascii占用一個(gè)字節(jié),而中文則為三個(gè)字節(jié),同時(shí)仍然以\n結(jié)尾,所以下面這種錯(cuò)誤的方法為
JNIEXPORT jstring JNICALL Java_Cwj_ShowLog(JNIEnv *env, jobject obj,jstring log)
{
printf("%s", log); //這樣做是錯(cuò)誤的,printf不能直接處理Java傳來的類型。
//dosomething 返回jstring等等。
}
而正確的轉(zhuǎn)換unicode到utf-8方法為使用GetStringUTFChars這個(gè)函數(shù):
JNIEXPORT jstring JNICALL Java_Cwj_ShowLog(JNIEnv *env, jobject obj,jstring log)
{
const jbyte *strDest;
strDest = (*env)->GetStringUTFChars(env, log, NULL);
if (strDest == NULL)
{
return NULL;//這里注意可能因?yàn)閮?nèi)存不足,需要拋出OutOfMemoryError異常,所以先返回空,有關(guān)JNI的異常處理我們將在以后的文章中詳細(xì)講解
}
printf("%s", strDest); //現(xiàn)在strDest可以用printf顯示了
(*env)->ReleaseStringUTFChars(env, prompt, strDest);//strDest用完了要釋放內(nèi)存
接下來我們還需要返回一個(gè)jstring類型的,我們可以讓用戶自己輸入,比如
char szBuf[255]; //分配一個(gè)緩沖區(qū)
scanf("%s", szBuf); //接收用戶輸入
return (*env)->NewStringUTF(env, szBuf); //返回一個(gè)utf-8的即jstring的字符串
}
4. 在JNI中獲取字符串的長度不能簡單的使用strlen這樣的函數(shù),對(duì)于不同的處理我們可以通過GetStringLength獲取一個(gè)Java的unicode類型(wchar_t*)的字符串長度,或者GetStringUTFLength獲取jni中的utf-8類型(char*)字符串長度。
5. 最后本文給網(wǎng)友一個(gè)分辨處理jni還是java類型的技巧,有關(guān)jni相關(guān)的字符或字符串處理均帶有utf關(guān)鍵字,
比如處理java的unicode類型的有:
GetStringChars/ReleaseStringChars GetStringLength NewStringGetStringRegion
而對(duì)應(yīng)jni的utf8類型的有:
GetStringUTFChars/ReleaseStringUTFChars GetStringUTFLengthNewStringUTF GetStringUTFRegion
有關(guān)Android的NDK JNI開發(fā)相關(guān)內(nèi)容我們將在下一篇文章中繼續(xù)講解。
聯(lián)系客服