我将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
}发布于 2012-09-14 09:09:29
不能缓存JNIEnv指针。阅读它,这里
JNI接口指针(JNIEnv)仅在当前线程中有效。如果另一个线程需要访问Java,它必须首先调用AttachCurrentThread()将自己附加到VM并获得一个JNI接口指针。一旦附加到VM,本机线程的工作方式就像运行在本机方法中的普通Java线程一样。本机线程一直连接到VM,直到它调用DetachCurrentThread()来分离自己。
您可以做的是缓存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.
}https://stackoverflow.com/questions/12420463
复制相似问题