[教育訓練紀錄] Android 的 JNI 開發,排名第一名的誤用是?

jollen 發表於 September 27, 2011 12:21 AM

Java 與 native code 的溝通介面稱為 JNI,這是 Android 底層開發的基本技術。不過,有許多 C 語言遺留下來的壤習慣,讓很多系統程式的開發者,一不小心就把 JNI 的程式碼寫錯。本週將會在一場論壇上說明幾個「誤用 C 語言」的例子,希望對 Android 底層開發的初學者有幫助。

近期在協助一家企業進行 Android 內訓,也遇到工程師問起「Java 如何與 C 傳遞資料」的問題,以傳遞陣列來說,其程式碼的寫法,跟傳統的 C 語言寫法有點不同。

從過去的教育訓練經驗裡也能歸納發現,排行榜第一名的誤用莫過於「陣列傳遞」,當 Java 透過 JNI 傳遞 Array 給 native code 時,native code 必須使用 JNI 的 GetIntArrayRegion() method 來讀取,而不是使用 C Pointer 的做法。

例如:

int intArrayAdd(int *num)
{
   int i, sum = 0;
   
   for (i = 0; i < 10; i++) {
      sum += num[i];
   }
}

換成 JNI 的話,應該改寫成:

intArraryAdd(JNIEnv *env, jobject obj, jintArray arr)
 {
     jint buf[10];
     jint i, sum = 0;
 
     (*env)->GetIntArrayRegion(env, arr, 0, 10, buf);
 
     for (i = 0; i < 10; i++) {
         sum += buf[i];
     }
     return sum;
 }

這裡的概念是,將陣列 copy 到 native code 裡後再使用。相關的完整說明,可參考「The Java Native Interface. Programmer's Guide and Specification」第 3.3 節。

Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue

您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw