我将JNIEnv存储在全局变量中,以便以后可以调用静态java方法。但是是否有必要存储指向JNIEnv的全局指针,它们会与任何其他Java对象一起使用,还是一种不需要这种情况的特殊情况。

JNIEnv* globalEnvPointer;

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

编辑

我在这里有点傻,所有在我的init中调用globalEnvPointer的方法都会被调用,因为init实际上是c程序的main方法,该方法直到程序结束才返回。我也没有在c程序中使用其他线程。我认为这简化了答案。
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
}

最佳答案

您不能缓存JNIEnv指针。阅读有关here:



您可以做的是改为缓存JavaVM指针。

static JavaVM *jvm;

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

然后,每当需要时,从没有给出上下文的上下文中使用JNIEnv指针,就可以这样做:
void someCallback() {
    JNIEnv *env;
    jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
    assert (rs == JNI_OK);
    // Use the env pointer...
}

但是,每当您从Java调用本机方法时,都会给出要使用的env指针:
JNIEXPORT jint JNICALL Java_package_Class_method(JNIEnv *env, jobject obj) {
    // just use the env pointer as is.
}

10-06 06:04