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