JNI學習總結——C/C++訪問Java類的屬性與方法
在C/C++原生代碼中訪問Java端的程式碼,一個常見的應用就是獲取類的屬性和呼叫類的方法。為了在C/C++中表示Java類的屬性和方法,JNI在Jni.h標頭檔案中定義了jfieldID和jmethodID型別來分別代表Java端的屬性和方法。
我們在訪問或設定Java屬性以及呼叫Java端方法的時候,首先就要在原生代碼中使用GetFieldID/GetMethodID取得代表該Java屬性或方法對應的ID才能進行相應的操作。
第一步:為了取得相應的ID,先要獲得Java物件的類。JNIEnv類中有如下幾個簡單的函式可以取得類:
jclass FIndClass ( const char* clsName );
jclass GetObjectClass ( jobject obj );
jclass GetSuperClass ( jclass obj );
FindClass()用於得到沒有例項物件的類,它會在classpath系統環境變數下尋找類,需要傳入完整類名,如:
jclasscls_string = env->FindClass( “ java/lang/String” );
GetobjectClass()顧名思義用於已經明確知道其物件,然後根據物件尋找類。
第二步:使用JNIEnv的GetFieldID/GetMethodID/GetStaticFieldID/GetStaticMethodID函式取得相應的jfieldID和jmethodID。
jfieldID GetFieldID ( jclass clazz , const char* name , const char* sign );
jfieldID GetStaticFieldID ( jclass clazz , const char* name , const char* sign );
jmethodID GetMethodID ( jclass clazz , const char* name , const char* sign );
jmethodID GetStaticMethodID ( jclass clazz, const char* name , const char* sign );
這四個函式中的對應引數含義是相同的,clazz是第一步中取得的類,name是Java物件中屬性或方法的名稱,sign是Java物件屬性或方法的簽名。
第三步:得到屬性或方法的ID之後,就可以根據該類的物件取得/設定Java屬性值,或者呼叫Java方法。
a) 取得/設定Java屬性值
成員變數在Java程式碼中宣告的型別分為兩大類:static型和非static型。分別使用函式GetStatic<TYPE>Field()和Get<TYPE>Field()可以獲得java屬性值。與之相對應的設定屬性值的函式為SetStatic<TYPE>Field()和Set<TYPE>Field(),其中<TYPE>是屬性對應的型別,可以取Int、Float、Short、Long、Double、Boolean、Byte和Object等八種類型。以int型為例:
jint GetIntField ( jobject obj , jfieldID fieldID );
void SetIntField( jobject obj , jfieldID fieldID , jint value);
第一個引數是該類的物件,第二個引數是屬性ID,value是要設定的值。
b) 呼叫java方法
呼叫Java函式的方法與獲得屬性值類似,也根據其方法返回值的type不同而不同,分為CallStatic<TYPE>Method( )和Call<TYPE>Method()。此時需要通過GetMethodID取得相應方法的jmethodID來傳入到上述函式的引數中。呼叫例項方法最常用的形式:
Call<TYPE>Method (jobject obj ,jmethodID id , …);