Ich habe erfahren, dass der JNI-Schnittstellenzeiger (JNIEnv *) nur im aktuellen Thread gültig ist. Angenommen, ich habe einen neuen Thread innerhalb einer nativen Methode gestartet. Wie kann es Ereignisse asynchron an eine Java-Methode senden? Da dieser neue Thread keine Referenz von (JNIEnv *) haben kann. Das Speichern einer globalen Variablen für (JNIEnv *) funktioniert anscheinend nicht?
java
c
multithreading
java-native-interface
Akhilesh
quelle
quelle
GetEnv
, sindAttachCurrentThread
undDetachCurrentThread
werden nicht einmal erklärt.Sie können einen Zeiger auf die JVM (
JavaVM*
) mit erhaltenJNIEnv->GetJavaVM
. Sie können diesen Zeiger sicher als globale Variable speichern. Später im neuen Thread können Sie entwederAttachCurrentThread
den neuen Thread an die JVM anhängen, wenn Sie ihn in C / C ++ erstellt haben, oder einfach,GetEnv
wenn Sie den Thread in Java-Code erstellt haben, was ich nicht annehme, da JNI IhnenJNIEnv*
dann und dann übergeben würde Sie würden dieses Problem nicht haben.// JNIEnv* env; (initialized somewhere else) JavaVM* jvm; env->GetJavaVM(&jvm); // now you can store jvm somewhere // in the new thread: JNIEnv* myNewEnv; JavaVMAttachArgs args; args.version = JNI_VERSION_1_6; // choose your JNI version args.name = NULL; // you might want to give the java thread a name args.group = NULL; // you might want to assign the java thread to a ThreadGroup jvm->AttachCurrentThread((void**)&myNewEnv, &args); // And now you can use myNewEnv
quelle
AttachCurrentThread
NULL sein kann, wenn Sie keine speziellen Einstellungen benötigen, und Sie sollten auf jeden Fall anrufen,DetachCurrentThread
wenn Sie fertig sind, wenn Sie zunächst nicht angehängt wurden (andernfalls sammeln Sie nutzloseThread
Objekte, die dies können werde nie GC'd sein).JNIEnv->GetJavaVM
akzeptiertenv
werden?env
Grunde der erste Parameter, da er über den Zeiger aufgerufen wird .GetJavaVM
env