传智播客第三讲,智播客第三讲
分享于 点击 21341 次 点评:152
传智播客第三讲,智播客第三讲
第三讲 本课程讲解在被调用的C/C++函数中如何取得/设定Java属性值、如何调用Java类的方法和调用Java类的父类的方法,并编写应用实例。
一、取得Java属性,设定Java属性值 取得了相应属性的jfieldID之后,就可以用Set<TYPE>Field, Get<TYPE>Field, SetStatic<TYPE>Field跟GetStatic<TYPE>Field等函数来对Java属性进行操作了。
Set/GetBooleanField
Set/GetByteField
Set/GetDoubleField
Set/GetFloatField
Set/GetIntField
Set/GetLongField
Set/GetShortField
Set/GetObjectField
Set/GetStaticBooleanField
Set/GetStaticByteField
Set/GetStaticDoubleField
Set/GetStaticFloatField
Set/GetStaticIntField
Set/GetStaticLongField
Set/GetStaticShortField
Set/GetStaticObjectField
二、怎么样获取数组属性呢?
可以使用GetObjectField来取得数组类型的属性。
示例: public class Hello {
public int number = 10; public native void test () ; public static void main( String [] args ) { Hello hello = new Hello (); hello . test() ; System .out . println( hello .number ) ; } }
JNIEXPORT void JNICALL Java_Hello_test ( JNIEnv * env , jobject obj){ jclass hello_clazz = env- >GetObjectClass ( obj) ; jfieldID id_number = env- >GetFieldID ( hello_clazz, "number", "I") ; jint number = env- >GetIntField ( obj, id_number ); cout << number << endl; env -> SetIntField( obj, id_number , 100L ) ; }
三、Java方法的调用
1)JNIEnv提供了众多的Call<TYPE>Method跟CallStatic<TYPE>Method,还有CallNonvirtual<TYPE>Method函数,需要通过GetMethodID取得相应方法的jmethodID来传入到上述函数的参数中。
2)调用实例方法的三种形式
Call<TYPE>Method(jobject obj, jmethodID id, ...);
Call<TYPE>MethodV(jobject obj, jmethodID id, va_list lst);
Call<TYPE>MethodA(jobject obj, jmethodID id, jvalue* v);
第一种是最常用的方式。
第二种是当调用这个函数的时候有一个指向参数表的va_list变量时使用的。
第三种是当调用这个函数的时候有一个指向jvalue或jvalue数组的指针时用的。
第一种:
env->CallBooleanMethod(obj, id_function, 100L, 3.44, L'3');
第三种:
boolean function(int i, double d, char c){
...
}
jvalue * args = new jvalue[3];
args[0].i = 100L;
args[1].d = 3.44;
args[2].c = L'3';
env->CallBooleanMethodA(obj, id_function, args);
delete [] args;
3)调用静态方法的三种形式
CallStatic<TYPE>Method(jclass clazz, jmethodID id, ...);
CallStatic<TYPE>MethodV(jobject obj, jmethodID id, va_list lst);
CallStatic<TYPE>MethodA(jobject obj, jmethodID id, jvalue* vars);
三、CallNonvirtual<TYPE>Method
1)思考一下吧
有如下C++代码:
class Father
{
public:
virtual void function()
{
cout << "father:func" << endl;
}
};
class child:public Father
{
public:
void function()
{
cout << "child:func" << endl;
}
};
想想这段代码调用的是哪个类的成员函数?父类函数去掉virtual和不去掉有区别的哦。
Father* p = new Child();
p->function();
2)在JNI中定义的CallNonvirtual<TYPE>Method就能够实现子类对象调用父类方法的功能。如果想要调用一个对象的父类的方法,而不是子类的这个方法的话,就可以使用CallNonvirtual<TYPE>Method。
3)要使用它,首先要取得父类及要调用的父类方法的jmethodID,然后传入到这个函数就能通过子类对象呼叫被复写(override)的父类的方法了。
4)测试代码:
public class Father { public void function(){ System .out . println( "father:function" ); }
public class child extends Father { public void function(){ System .out . println( "child:function" ); }
}
public class Hello {
Father p = new child (); public native void test () ; public static void main( String [] args ) { Hello hello = new Hello (); hello . test() ; } }
JNIEXPORT void JNICALL Java_Hello_test ( JNIEnv * env , jobject obj){ jclass hello_clazz = env- >GetObjectClass ( obj) ; jfieldID id_p = env- >GetFieldID ( hello_clazz, "p", "Lcom/example/jnitest1/Father;" ) ; jobject p = env- >GetObjectField ( obj, id_p ); jclass clazz_Father = env- >FindClass ( "com/example/jnitest1") ; jmethodID id_Father_function = env- >GetMethodID ( clazz_Father, "function", "()V" ); // env->CallVoidMethod(p, id_Father_function); env -> CallNonvirtualVoidMethod( p , clazz_Father , id_Father_function) ; }
相关文章
- 暂无相关文章
用户点评