首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >保持对JNIEnv环境的全局引用

保持对JNIEnv环境的全局引用
EN

Stack Overflow用户
提问于 2012-09-14 08:08:43
回答 1查看 13.4K关注 0票数 39

我将JNIEnv存储在全局中,以便以后可以调用静态java方法。但是,存储指向JNIEnv的全局指针是必要的,它们与任何其他java对象一样,还是不需要这样做的特例。

代码语言:javascript
复制
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程序中也没有使用其他线程。我认为这简化了答案。

代码语言:javascript
复制
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
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-09-14 09:09:29

不能缓存JNIEnv指针。阅读它,这里

JNI接口指针(JNIEnv)仅在当前线程中有效。如果另一个线程需要访问Java,它必须首先调用AttachCurrentThread()将自己附加到VM并获得一个JNI接口指针。一旦附加到VM,本机线程的工作方式就像运行在本机方法中的普通Java线程一样。本机线程一直连接到VM,直到它调用DetachCurrentThread()来分离自己。

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

代码语言:javascript
复制
static JavaVM *jvm;

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

然后,无论何时您需要从上下文中获得JNIEnv指针,如果没有给出它,就执行以下操作:

代码语言:javascript
复制
void someCallback() {
    JNIEnv *env;
    jint rs = (*jvm)->AttachCurrentThread(jvm, &env, NULL);
    assert (rs == JNI_OK);
    // Use the env pointer...
}

但是,每当从Java调用本机方法时,就会给出要使用的env指针:

代码语言:javascript
复制
JNIEXPORT jint JNICALL Java_package_Class_method(JNIEnv *env, jobject obj) {
    // just use the env pointer as is.
}
票数 55
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12420463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档