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:
public void showCar(){
doSomething()
}
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 ideas to provide you:
…
jclass clazz = env->FindClass(“com/path/to/the/class”);
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.
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.
…
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:
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:
This will pickup things like security violations when trying to do reflection when it might not be allowed.
…
Another idea to remove the FindClass() call. This would work with any class that GetMethodID worked on, kind of like dyhamic typing / late-binding.