tutorial r16 r13 ndk nazareno ejemplos c jni jnienv

r16 - Mantener una referencia global al entorno JNIEnv.



ndk r13 (1)

Estoy almacenando JNIEnv en un global para poder llamar a métodos de Java estáticos más adelante. Pero no es necesario almacenar un puntero global al JNIEnv , tal como lo haríamos con cualquier otro objeto Java, o es un caso especial que no requiere esto.

JNIEnv* globalEnvPointer; [JNICALL etc] void init(JNIENv* env, [etc]) { //required? globalEnvPointer = (JNIENv*) (env*)->GetGlobalRef(env, env); //or is this OK? globalEnvPointer = env; }

Editar

Aquí estoy un poco tonto, todos los métodos que usarán globalEnvPointer se invocan dentro de mi init porque my init es en realidad el método main mi programa c , que no volverá hasta el final del programa. Tampoco estoy usando otros hilos en el programa c Creo que esto simplifica la respuesta.

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 }


No puede JNIEnv puntero JNIEnv caché. Lea sobre esto here :

El puntero de la interfaz JNI (JNIEnv) solo es válido en el hilo actual. Si otro subproceso necesita acceder a la VM de Java, primero debe llamar a AttachCurrentThread () para adjuntarse a la VM y obtener un puntero de interfaz JNI. Una vez conectado a la máquina virtual, un subproceso nativo funciona igual que un subproceso Java normal que se ejecuta dentro de un método nativo. El subproceso nativo permanece adjunto a la máquina virtual hasta que llama a DetachCurrentThread () para separarse.

Lo que puedes hacer es JavaVM puntero de JavaVM en caché.

static JavaVM *jvm; [JNICALL etc] void init(JNIENv* env, [etc]) { jint rs = (*env)->GetJavaVM(env, &jvm); assert (rs == JNI_OK); }

Y luego, cuando sea necesario, a continuación, puntero JNIEnv desde un contexto donde no se le da hacer esto:

void someCallback() { JNIEnv *env; jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL); assert (rs == JNI_OK); // Use the env pointer... }

Pero cada vez que se llama a un método nativo de Java, se proporciona el puntero env a usar:

JNIEXPORT jint JNICALL Java_package_Class_method(JNIEnv *env, jobject obj) { // just use the env pointer as is. }