JNI 的CallXXMethod 与 CallNonVirtualXXMethod
看一些资料,说 callNonVirtual<>method 是类似于c++里面父类声明的非抽抽象函数,并且有个例子
public class Father { @Override public void fun() { // TODO Auto-generated method stub Log.d("333", "Father involked"); } } public class Child extends Father{ @Override public void fun() { // TODO Auto-generated method stub Log.d("333", "Child involked"); } }
在如果定义
Father instance = new Child();
在C++中如下调用
jobject fObj = env->GetObjectField(obj,fID); jclass fclass=env->FindClass("lc/test/jni/Father"); jmethodID fm= env->GetMethodID(fclass,"fun","()V"); env->CallNonvirtualVoidMethod(fObj,fclass,fm);
那么最后的结果是调用的Father类的fun函数。
但是如果 father继承grandfather,那调用callNonVirtual<>method的时候是调用的father的函数还是grandfather的函数呢?
经过试验发现,调用哪个函数,是callNonVirtual<>method的第二个参数决定的。代码就不写了
PS: 顺带说下 FindClass( ) 和 getObjectClass( )的区别,因为在写上面的测试代码的时候我出过这个错
FindClass( ) 就是通过包名类名去找,这个相当于绝对路径吧
getObjectClass( ) 是通过一个obj的类型去找,这个地方需要注意的是,他是通过对象类型去找,不是通过引用类型去找
比如一开始在java 里面写了
Father p=new Child();
那么在C++里面获得这个obj之后,如果用getObjectClass( ) 获得的就是 Child 的 Class , 不是 Father 的 Class
转自:https://www.xuebuyuan.com/1698025.html
代码讲解 - 调用父类实例方法
如果一个方法被定义在父类中,在子类中被覆盖,也可以调用父类中的这个实例方法。JNI 提供了一系列函数CallNonvirtualXXXMethod来支持调用各种返回值类型的实例方法。调用一个定义在父类中的实例方法,须遵循下面的步骤:
1.使用GetMethodID函数从一个指向父类的Class引用当中获取方法ID
cls_animal = (*env)->FindClass(env, "com/study/jnilearn/Animal");
if (cls_animal == NULL) {
return;
}
//例1: 调用父类的run方法
mid_run = (*env)->GetMethodID(env, cls_animal, "run", "()V"); // 获取父类Animal中run方法的id
if (mid_run == NULL) {
return;
}
2.传入子类对象、父类Class引用、父类方法 ID 和参数,并调用 CallNonvirtualVoidMethod、
CallNonvirtualBooleanMethod、CallNonvirtualIntMethod等一系列函数中的一个。其中CallNonvirtualVoidMethod 也可以被用来调用父类的构造函数。
// 注意:obj_cat是Cat的实例,cls_animal是Animal的Class引用,mid_run是Animal类中的方法ID
(*env)->CallNonvirtualVoidMethod(env, obj_cat, cls_animal, mid_run);
其实在开发当中,这种调用父类实例方法的情况是很少遇到的,通常在 JAVA 中可以很简单地做到: super.func();但有些特殊需求也可能会用到,所以知道有这么回事还是很有必要的。
推荐阅读
-
JNI接口 创建一个Java调用C++实例 涉及JAVA与C++之间的参数传递问题
-
Android JNI中jfloatArray与jfloat*的相互转换
-
JNI 的CallXXMethod 与 CallNonVirtualXXMethod
-
JNI的学习与实践所得(Android)
-
Android JNI实现Java与C/C++互相调用,以及so库的生成和调用(JNI方式调用美图秀秀so)
-
Android JNI中jfloatArray与jfloat*的相互转换
-
JNI接口 创建一个Java调用C++实例 涉及JAVA与C++之间的参数传递问题
-
Android JNI开发---java与c++之间的中文字符串传递
-
Android JNI开发---java与c++之间的中文字符串传递