C 保持对JNIEnv环境的全局引用
我将offC 保持对JNIEnv环境的全局引用,c,java-native-interface,jnienv,C,Java Native Interface,Jnienv,我将offJNIEnv存储在一个全局文件中,以便稍后调用静态java方法。但是,是否有必要像存储任何其他java对象那样存储指向JNIEnv的全局指针,还是不需要这样做的特殊情况 JNIEnv* globalEnvPointer; [JNICALL etc] void init(JNIENv* env, [etc]) { //required? globalEnvPointer = (JNIENv*) (env*)->GetGlobalRef(env, env); //
JNIEnv
存储在一个全局文件中,以便稍后调用静态java方法。但是,是否有必要像存储任何其他java对象那样存储指向JNIEnv
的全局指针,还是不需要这样做的特殊情况
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
指针。请阅读:
JNI接口指针(JNIEnv)仅在当前线程中有效。如果另一个线程需要访问Java VM,它必须首先调用AttachCurrentThread()将自身连接到VM并获取JNI接口指针。一旦连接到VM,本机线程的工作方式与在本机方法中运行的普通Java线程类似。本机线程在调用DetachCurrentThread()以分离自身之前一直保持与VM的连接
您可以做的是缓存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.
}
都是一根线,有区别吗?i、 我的
init
是在同一个线程中调用的,这个线程稍后将调用静态java方法?在我看来,将临时数据存储在全局变量中以供其他方法使用是一种反模式。是的,我同意,但我正在尝试使用大量的c
源代码库,并用java重写100多个汇编方法(如someCallback
)。我们说的是执行调用的数千个位置。另外,同样的源代码库仍然应该为其原始目标编译,因此传递JNIEnv
实际上是一个丑陋的解决方案。感谢所有的提示,如果我需要使用线程,我会把它们记在心里。如果已经有通过JavaVM的JNI_OnLoad,我不会创建自己的init函数。@maba:OP可能需要一个单独的init函数,但他也可能根本不知道JNI_OnLoad的存在。它只是扩展了答案。它不是批评,只是一个友好的小扩展提示。我不写我自己的答案,因为我认为你的答案已经很好了,你应该得到分数。然而,也要考虑其他人阅读你的答案,而不仅仅是OP,他们下面有经验丰富和没有经验的人。