Len*_*art 8 java-native-interface android
我试图从Android应用程序中的本机C代码调用java方法.使用JNI听起来很简单,但是当我最终调用方法本身时,我的代码总是崩溃.这是我的代码:Native C Code:
JNIEXPORT void JNICALL
Java_com_path_to_my_package_renderStuff(JNIEnv* env, jobject jobj){
//...
jclass clazz = env->FindClass("com/path/to/the/class");
jmethodID showCar = env->GetMethodID(clazz,"showCar","()V" );
env->CallVoidMethod(jobj,showCar); //If I comment this out, it won't crash
//...
}
Run Code Online (Sandbox Code Playgroud)
Java代码:
public void showCar(){
doSomething()
}
Run Code Online (Sandbox Code Playgroud)
doSomething()甚至没有达到,我可以在那里设置断点,永远不会被击中.如上所述,只要我注释掉CallVoidMethod调用,它就不会崩溃,但显然也不会调用showCar().任何提示?
Dar*_*les 11
4个想法为您提供:
...
jclass clazz = env-> FindClass("com/path/to/the/class");
你能否确认名称不是"com/path/to/the/MyClass",其中classname是大写的第一个字符,显然名称"class"是一个保留字.在您的示例中,使用JNI C符号名称"Java_com_path_to_my_package_renderStuff"与"com/path/to/the/class"上的FindClass()查找之间存在轻微的差异.但由于您的stackoverflow不是关于UnsatisfiedLinkageError,我只能猜测您提供的示例与自身不一致.
使用我的示例,我希望JNI C符号名称为"Java_com_path_to_the_MyClass_renderStuff",并且"com/path/to/the/MyClass"上的FindClass()查找.对于链接目的,使用大写的第1个字母和小写的方法名称的第1个字母可能很重要.
...
你确定传递的"jobj"与你正在查找的"com/path/to/the/class"的类型相同吗?也许在你的Java代码中,你可以用你的原生包装:
public void renderStuff() {
if((this instanceof com.path.to.the.MyClass) == false)
throw new RuntimeException("Unexpected class expected: com.path.to.the.MyClass");
renderStuff_internal();
}
private native void renderStuff_internal();
Run Code Online (Sandbox Code Playgroud)
这将确保Java代码中的问题而不会导致JVM崩溃.您还需要调整C符号名称以将"_1internal"附加到末尾,使"Java_com_path_to_the_MyClass_renderStuff_1internal"(额外的"1"字符是预期的)
...
也许在你列出的每个语句之间尝试使用belt和braces异常检查:
if(env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
Run Code Online (Sandbox Code Playgroud)
当尝试在可能不允许的情况下进行反射时,这会拾取安全违规等内容.
...
jclass cls = env->GetObjectClass(jobj); // instead of FindClass
jmethodID mid = env->GetMethodID(cls, "showCar", "()V");
if(!mid) return; // whoops method does not exist
env->CallVoidMethod(jobj, mid);
Run Code Online (Sandbox Code Playgroud)
删除FindClass()调用的另一个想法.这适用于GetMethodID工作的任何类,有点像dyhamic类型/后期绑定.
| 归档时间: |
|
| 查看次数: |
17193 次 |
| 最近记录: |