JNI:取得Java屬性和設(shè)置Java屬性值
1. 取得Java屬性/設(shè)定Java屬性值
獲得了相應(yīng)屬性的jfieldID之后,就可以使用
SetField GetField SetStaticField GetStaticField
等函數(shù)來對Java屬性進行操作了。
類實例方法
Set/GetBooleanFieldSet/GetByteFieldSet/GetDoubleFieldSet/GetFloatFieldSet/GetIntFieldSet/GetLongFieldSet/GetShortFieldSet/GetObjectField
類靜態(tài)方法
Set/GetStaticBooleanFieldSet/GetStaticByteFieldSet/GetStaticDoubleFieldSet/GetStaticFloatFieldSet/GetStaticIntFieldSet/GetStaticLongFieldSet/GetStaticShortFieldSet/GetStaticObjectField
怎樣獲取數(shù)組的屬性呢?
可以使用GetObjectField來獲取數(shù)組類型的屬性。不過JNI提供了一系列方法獲取數(shù)組的屬性,后續(xù)介紹。
2. 案例
在C/C++中修改Java中的屬性
package com.omg;public class TestNative {public int number;public native void sayHello();}
C++代碼
jclass clazz_TestNative = env->GetObjectClass( obj);jfieldID id_number = env->GetFieldID(clazz_TestNative, "number", "I");jint number = env->GetIntFiled(obj, id_number);count << number << endl;env->SetIntField(obj, id_number, 100L);
3. Java方法調(diào)用
JNIEnv提供了眾多的 Call
Method 與 CallStatic Method,還有CallNonvirtual Method函數(shù)。需要通過GetMethodID取得相應(yīng)方法的jmethodID來傳入上述函數(shù)的參數(shù)中。 調(diào)用實例方法的三種形式
CallMethod( jobject obj, jmethodID id, ...); CallMethodV( jobject obj, jmethodID id, va_list lst); CallMethodA( jobject obj, jmethodID id, jvalue* v);
第一種是最常用的方式
第二種是當(dāng)調(diào)用這個函數(shù)的時候,有一個指向參數(shù)表的va_list變量時使用(不常用)
第三種是當(dāng)調(diào)用這個函數(shù)的時候,有一個指向jvalue或者jvalue數(shù)組的指針時使用
調(diào)用靜態(tài)方法的三種形式
CallStaticMethod( jclass clazz, jmethodID id, ...); CallStaticMethodV( jclass clazz, jmethodID id, va_list lst); CallStaticMethodA( jclass clazz, jmethodID id, jvalue* v);
偽代碼
java:public boolean function(int i, double d, char c){//......}Cenv->CallBooleanMethod(obj, id_function, 100L, 1.11, L'3')jvalue * args = new jvalue[3];args[0].i = 100L;args[1].d = 3.44;args[2].c = L'3';env->CallBooleanMethod( obj, id_function, args);delete [] args;
4. 案例
在C/C++中代用Java中的方法
Java代碼
package com.omg;public?class?TestNative?{public max(double num1, double num2){return num1 > num2 ? num1 : num2;????}}
C++代碼
jclass clazz_TestNative = env->GetObjectClass( obj );jmethodID id_max = env->GetMetodID( clazz_TestNative, obj, "(DD)D");jdouble maxVal = env->GetDoubleMethod(obj, id_max, 2.1, 3.14);cout << maxVal << endl;
5. CallNonvirtual
有如下Java代碼
public class Father {public void function(){?????? System.out.println("Father?function");????????}}???public?class?Child?extends?Father?{public void function(){System.out.println("Child function");}}
想想這段Java代碼調(diào)用的是哪個類的方法?
Father p = new Child();p.function();
如果想調(diào)用父類的function是沒有辦法的
有如下C++代碼
class Father {public:????void?function(){????????cout?<"Father?function"?<}}??class?Child?:?public?Father?{public:void function(){????????cout?<"Child?function"?<}}
想想這段代碼調(diào)用的是哪個類的成員函數(shù)?(調(diào)用的是父類的函數(shù))
Father* p = new Child();p->function();
C++有虛函數(shù)的概念,修改一下父類加一個 virtual
class Father {public:virtual void function(){??? cout?<"Father?function"?<<endl;}}class Child : public Father {public:void function(){??????????cout?<"Child?function"?<<endl;}}
再想想這段代碼調(diào)用的是哪個類的成員函數(shù)?(調(diào)用的是子類的函數(shù))
Father* p = new Child();p->function();
在Java語言中,所有的函數(shù)都是虛函數(shù)
在JNI中定義了CallNonvirtual
Method就能實現(xiàn)子類對象調(diào)用父類方法的功能,如果想要調(diào)用一個對象的父類的方法,而不是子類的重寫(over write)的方法的話,就可以使用CallNonVirtual Method 要使用CallNonVirtual
Method,首先要取得父類及要調(diào)用的父類的方法的jmethodID。然后傳入到這個函數(shù)就能通過子類對象調(diào)用被重寫(over write)的父類的方法
5. 案例
package com.omg;public class Father {public void function() {????? System.out.println("Father?function");}}package com.omg;public class Child extends Father {public void function() {????????System.out.println("Child?function");}}
測試
Java定義成員變量
public Father p = new Child();C++代碼
jclass clazz_TestNative = env->GetObjectClass( obj );jfieldID id_p = env->GetFieldID(clazz_TestNative, "p", "Lcom/omg/Father;");jobject p = env->GetObjectField(obj, id_p);jclass clazz_Father = env->FindClass( "Lcom/omg/Father;" );jmethodID id_Father_function = env->GetMethodID(clazz_Father, "function", "()V");env->CallVoidMethod(p, id_Father_function);env->CallNonvirtualVoidMethod(p, clazz_Father, id_Father_function);

分享&在看
