以下是4个建议:
...
jclass clazz = env->FindClass("com/path/to/the/class");
请确认名称不是"com/path/to/the/MyClass",其中类名的首字母大写,并且"name"是一个保留字。在您的示例中,JNI C符号名称"Java_com_path_to_my_package_renderStuff"的使用方式与"FindClass()"查找"com/path/to/the/class"存在轻微差异。但由于您的stackoverflow问题与UnsatisfiedLinkageError无关,因此我只能猜测您提供的示例本身不一致。
使用我的示例,我预计JNI C符号名称为"Java_com_path_to_the_MyClass_renderStuff",并且"FindClass()"查找的内容为"com/path/to/the/MyClass"。类名以大写字母开头,方法名以小写字母开头可能对于链接很重要。
...
您确定传递的"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();
如何在不导致JVM崩溃的情况下确保Java代码中的问题。您还需要调整C符号名称,将“_1internal”附加到末尾,使其变为“Java_com_path_to_the_MyClass_renderStuff_1internal”(意在多余的“1”字符)。
...
也许可以在每个列出的语句之间进行多重异常检查:
if(env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
这将会捕捉到一些安全违规,例如在可能不允许使用反射的情况下尝试使用它。
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可用的类,就像动态类型/后期绑定一样。
FindClass
和GetMethodID
返回的不是空值吗? - Stuart Cook