gpt4 book ai didi

c - 保持对 JNIEnv 环境的全局引用

转载 作者:太空狗 更新时间:2023-10-29 16:21:24 24 4
gpt4 key购买 nike

我将 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;
}

编辑

我在这里有点笨,所有将使用 globalEnvPointer 的方法都在我的 init 中调用,因为我的 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 :

The JNI interface pointer (JNIEnv) is valid only in the current thread. Should another thread need to access the Java VM, it must first call AttachCurrentThread() to attach itself to the VM and obtain a JNI interface pointer. Once attached to the VM, a native thread works just like an ordinary Java thread running inside a native method. The native thread remains attached to the VM until it calls DetachCurrentThread() to detach itself.

您可以做的是缓存 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 调用 native 方法时,都会给出要使用的 env 指针:

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

关于c - 保持对 JNIEnv 环境的全局引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12420463/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com