I\'m trying to use a JNI function to create a Java class and set some properties of that class using the DeviceId.java constructor method. I\'m able to get the constructor
When you called GetMethodID, you provided the signature for the two-arg constructor. Thus, you just need to pass your jstring and a jbytearray when you call NewObject - for example:
return (*env)->NewObject(env, c, cnstrctr, id, cache);
You don't need to call the setId and setCache methods unless you decide to call the 0-arg constructor - and that just complicates your code since you'll have to call GetMethodID for those and call them. Simpler to continue down the route you're on.
I wanted to return a custom Java object from JNI's cpp code back to Java. The solution is to return a jobject from cpp function and use our custom Java object in native method declaration.
public class PyError {
public String message;
public boolean occurred;
public PyError(boolean occurred, String message){
this.message = message;
this.occurred = occurred;
}
}
and method declaration in Java:
native PyError nativePythonErrorOccurred();
on the cpp side:
extern "C" JNIEXPORT jobject JNICALL
Java_com_your_package_nativePythonErrorOccurred(JNIEnv *env, jobject obj) {
jclass javaLocalClass = env->FindClass("com/your/package/PyError");
if (javaLocalClass == NULL) {
LOGP("Find Class Failed.\n");
} else {
LOGP("Found class.\n");
}
jclass javaGlobalClass = reinterpret_cast<jclass>(env->NewGlobalRef(javaLocalClass));
// info: last argument is Java method signature
jmethodID javaConstructor = env->GetMethodID(javaGlobalClass, "<init>", "(ZLjava/lang/String;)V");
if (javaConstructor == NULL) {
LOGP("Find method Failed.\n");
} else {
LOGP("Found method.\n");
}
jobject pyErrorObject = env->NewObject(javaGlobalClass, javaConstructor, true, env->NewStringUTF("Sample error body"));
return pyErrorObject;
}
Determine the signature of the method using
javap -s java.your.package.YourClass.
Also, have a look here.
If you encounter error similar to: JNI ERROR (app bug): attempt to use stale Global 0xf2ac01ba your method signature is wrong, you're passing wrong arguments to env->NewObject() or you're not using global state of jni objects - more here.