Here I create a class in JAVA in which I have function (callback) which I must call from C file.
class DSMInitializeClassParameter {
/**
* Callback
Another way to ensure that you get a reference to the JavaVM as the first order of business is to add the JNI_OnLoad
method and cache the reference. This will be called when the shared library gets loaded.
Ex.
static JavaVM* cachedJVM;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
{
cachedJVM = jvm;
// ... Any other initialization code.
}
Once you have the ref to the JavaVM pointer you can then use the method Michael Mrozek described in the above post.
It's generally unsafe to cache a JNIEnv*
instance and keep using it, as it varies depending on the currently active thread. You can save a JavaVM*
instance, which will never change. In a native initializer function, call GetJavaVM
and pass it the address of a JavaVM
pointer:
static JavaVM *jvm;
JNIEXPORT void JNICALL Java_SomeClass_init(JNIEnv *env, jclass) {
int status = (*env)->GetJavaVM(env, &jvm);
if(status != 0) {
// Fail!
}
}
Now you can use that JavaVM*
to get the current JNIEnv*
with AttachCurrentThread:
dsmResult_t dsmInitializeCall( dsmResult_t status, void * pUserData, dsmEvent_t * hEvent ) {
JNIEnv *env;
(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
(*env)->CallVoidMethod(env, classObject, mid);
}