调用CallVoidMethod时JNI崩溃 [英] JNI crashes when calling CallVoidMethod

查看:3293
本文介绍了调用CallVoidMethod时JNI崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图调用从本机C code Java方法在Android应用程序。这听起来与JNI的使用非常简单,但我的code老是死机的时候终于调用该方法本身。 这是我的code: 本机C code:

I'm trying to call a java method from native C code in an Android Application. This sounds quite simple with the usage of JNI, but my code always crashes when finally calling the method itself. Here's my code: 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
//...
}

Java的code:

Java Code:

public void showCar(){      
    doSomething()
}

DoSomething的()甚至没有达到,我可以设置一个断点出现,这将永远不会被击中。正如上面所说的,只要我注释掉CallVoidMethod电话时,它不会崩溃,但显然不是叫showCar()两种。任何提示?

doSomething() isn't even reached, I can set a breakpoint there, which will never be hit. And as said above, as soon as I comment out the CallVoidMethod call, it won't crash but obviously not call showCar() either. Any hints?

推荐答案

4的想法,为您提供:

4 ideas to provide you:

...

JCLASS clazz中= ENV->的findClass(COM /路径/到/的/班);

您可以确认的名称不是COM /路径/到/的/ MyClass的,其中的类名是大写的第1个字符,显然命名为类是一个保留字。有关于使用JNI C符号名Java_com_path_to_my_package_renderStuff和的findClass()查询之间的轻微discrepencyCOM /路径/到/的/班在你的榜样。但由于你的计算器是不是一个关于UnsatisfiedLinkageError我只能猜测你的榜样提供不与自己保持一致。

Can you confirm the name is not "com/path/to/the/MyClass" where the classname is uppercase 1st character and obviously the name "class" is a reserved word. There is a slight discrepency between the use of the JNI C symbol name "Java_com_path_to_my_package_renderStuff" and the FindClass() lookup on "com/path/to/the/class"in your example. But since your stackoverflow is not a about UnsatisfiedLinkageError I can only guess your example provided is not consistent with itself.

使用我的例子,我希望JNI的C符号的名称为Java_com_path_to_the_MyClass_renderStuff和COM /路径/到/的/ MyClass的中的findClass()查询。利用类和方法名小写第一个字母大写第一个字母可能是联动的目的很重要的。

Using my example I would expect the JNI C symbol name to be "Java_com_path_to_the_MyClass_renderStuff" and the FindClass() lookup on "com/path/to/the/MyClass". The use of uppercase 1st letter of class and lowercase 1st letter of method name might be important for linkage purposes.

...

您确定jobj传递的是相同类型的COM /路径/到/的/班您正在寻找吗?也许在你的Java code你可以用你的母语:

Are you sure the "jobj" being passed is the same type as the "com/path/to/the/class" you are looking up ? Maybe in your Java code you can wrap your native with:

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();

这将确保Java的code这个问题,而不会导致JVM崩溃。您还需要调整您的C符号名追加_1internal到最终决策Java_com_path_to_the_MyClass_renderStuff_1internal(额外的1字意)

Which will ensure that matter in Java code without causing a JVM crash. You would also need to adjust your C symbol name to append the "_1internal" onto the end making "Java_com_path_to_the_MyClass_renderStuff_1internal" (the extra "1" character is intended)

...

也许尝试带和背带异常每次列出有关声明的检查:

Maybe try belt and braces exception checking in between each statement you list about:

if(env->ExceptionCheck()) {
    env->ExceptionDescribe();
    env->ExceptionClear();
}

这将尝试在做反思时,它可能不会被允许皮卡之类的安全违规行为。

This will pickup things like security violations when trying to do reflection when it might not be allowed.

...

 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);

另一个想法删除的findClass()调用。这与的GetMethodID工作的任何一类的工作类型的,像dyhamic打字/后期绑定。

Another idea to remove the FindClass() call. This would work with any class that GetMethodID worked on, kind of like dyhamic typing / late-binding.

这篇关于调用CallVoidMethod时JNI崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆