JNI/NDK開發指南(3):JNI資料型別及與Java資料型別的對映關係

發表於2015-03-19

當我們在呼叫一個Java native方法的時候,方法中的引數是如何傳遞給C/C++本地函式中的呢?Java方法中的引數與C/C++函式中的引數,它們之間是怎麼轉換的呢?我猜你應該也有相關的疑慮吧,我們們先來看一個例子,還是以HelloWorld為例:

HelloWorld.java:

在HelloWorld.java中定義了一個test的native方法,該方法中一個共有12個引數,其中前面8個為基本資料型別,後面4個全部為引用型別。

由HelloWorld.class生成的native函式原型及實現:

呼叫test方法的輸出結果:

從標頭檔案函式的原型可以得知,test方法中形參的資料型別自動轉換成了JNI中相應的資料型別,不難理解,在呼叫Java native方法將實參傳遞給C/C++函式的時候,會自動將java形參的資料型別自動轉換成C/C++相應的資料型別,所以我們在寫JNI程式的時候,必須要明白它們之間資料型別的對應關係。

在Java語言中資料型別分為基本資料型別和引用型別,其中基本資料型別有8種:byte、char、short、int、long、float、double、boolean,除了基本資料型別外其它都是引用型別:Object、String、陣列等。8種基本資料型別分別對應JNI資料型別中的jbyte、jchar、jshort、jint、jlong、jfloat、jdouble、jboolean。所有的JNI引用型別全部是jobject型別,為了使用方便和型別安全,JNI定義了一個引用型別集合,集合當中的所有型別都是jobject的子類,這些子類和Java中常用的引用型別相對應。例如:jstring表示字串、jclass表示class位元組碼物件、jthrowable表示異常、jarray表示陣列,另外jarray派生了8個子類,分別對應Java中的8種基本資料型別(jintArray、jshortArray、jlongArray等)。下面再回顧頭來看看test方法與Java_com_study_jnilearn_HelloWorld_test函式中引數型別的對應關係:

從上面兩個函式的引數中可以看出來,除了JNIEnv和jclass這兩個引數外,其它引數都是一一對應的。下面是JNI規範文件中描述Java與JNI資料型別的對應關係:

基本資料型別:

引用型別:

注意:

1、JNI如果使用C++語言編寫的話,所有引用型別派生自jobject,使用C++的繼承結構特性,使用相應的型別。如下所示:

2、JNI如果使用C語言編寫的話,所有引用型別使用jobject,其它引用型別使用typedef重新定義,如:typedef jobject jstring

jvalue型別:

jvalue是一個unio(聯合)型別,在C語中為了節約記憶體,會用聯合型別變數來儲存宣告在聯合體中的任意型別資料 。在JNI中將基本資料型別與引用型別定義在一個聯合型別中,表示用jvalue定義的變數,可以儲存任意JNI型別的資料,後面會介紹jvalue在JNI程式設計當中的應用。原型如下:

如果對unio型別不太明白的同學,請參考相關資料,在這裡不細講。

相關文章