Ich speichere ab JNIEnv
in einem globalen, damit ich später statische Java-Methoden aufrufen kann. Aber ist es notwendig, einen globalen Zeiger auf die zu speichern JNIEnv
wie man es mit jedem anderen Java-Objekt tun würde, oder ist es ein Sonderfall, der dies nicht erfordert.
JNIEnv* globalEnvPointer;
[JNICALL etc] void init(JNIENv* env, [etc])
{
//required?
globalEnvPointer = (JNIENv*) (env*)->GetGlobalRef(env, env);
//or is this OK?
globalEnvPointer = env;
}
Bearbeiten
Ich bin hier ein bisschen dumm, alle Methoden, die verwendet werden globalEnvPointer
werden in meiner Init aufgerufen, weil meine init
ist eigentlich mein c
Programm main
-Methode, die erst am Ende des Programms zurückkehrt. Ich verwende auch keine anderen Threads im C-Programm. Ich denke, das vereinfacht die Antwort.
JNIEnv* globalEnvPointer;
[JNICALL etc] void main(JNIENv* env, [etc])
{
//required?
globalEnvPointer = (JNIENv*) (env*)->GetGlobalRef(env, env);
//or is this OK?
globalEnvPointer = env;
someMethod();
}
void someMethod()
{
//use globalEnvPointer here
}
Sie können die nicht zwischenspeichern JNIEnv
Zeiger. Lese darüber hier:
Der JNI-Schnittstellenzeiger (JNIEnv) ist nur im aktuellen Thread gültig. Sollte ein anderer Thread auf die Java VM zugreifen müssen, muss er zuerst AttachCurrentThread() aufrufen, um sich selbst an die VM anzuhängen und einen JNI-Schnittstellenzeiger zu erhalten. Einmal mit der VM verbunden, funktioniert ein nativer Thread genau wie ein gewöhnlicher Java-Thread, der innerhalb einer nativen Methode ausgeführt wird. Der native Thread bleibt mit der VM verbunden, bis er DetachCurrentThread() aufruft, um sich selbst zu trennen.
Was Sie tun können, ist, die Datei zwischenzuspeichern JavaVM
Zeiger statt.
static JavaVM *jvm;
[JNICALL etc] void init(JNIENv* env, [etc])
{
jint rs = (*env)->GetJavaVM(env, &jvm);
assert (rs == JNI_OK);
}
Und dann, wann immer Sie es brauchen JNIEnv
Zeiger aus einem Kontext, in dem es nicht gegeben ist, tun Sie dies:
void someCallback() {
JNIEnv *env;
jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
assert (rs == JNI_OK);
// Use the env pointer...
}
Aber immer wenn Sie eine native Methode von Java aufrufen, wird der zu verwendende env-Zeiger angegeben:
JNIEXPORT jint JNICALL Java_package_Class_method(JNIEnv *env, jobject obj) {
// just use the env pointer as is.
}