1. 程式人生 > >JNI學習總結——C/C++訪問Java類的屬性與方法

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 , …);