出于某种原因,当我尝试从一个线程访问一个java对象(在整个程序中持续存在BTW)时,程序崩溃了。这里有一个简单的例子来证明这个问题:
#include <jni.h>
#include <pthread.h>
pthread_t thread;
jobject object;
JavaVM* jvm;
/*
Our thread function:
*/
void* run( void* );
extern "C" void Java_com_Program_Initialize( JNIEnv* jnv, jobject caller )
{
object = caller;
jnv->GetJavaVM( &jvm );
/*
Before launching our thread, this works just fine:
*/
jnv->CallVoidMethod( object, jnv->GetMethodID( jnv->GetObjectClass( object ), "foo", "()V" ) );
pthread_create( &thread, NULL, run, NULL );
}
void* run( void* )
{
JNIEnv* jnv;
jvm->AttachCurrentThread( &jnv, NULL );
/*
Within the context of our thread however, this crashes:
*/
jnv->CallVoidMethod( object, jnv->GetMethodID( jnv->GetObjectClass( object ), "foo", "()V" ) );
jvm->DetachCurrentThread( );
return NULL;
}
关于出了什么问题的任何想法?
答案 0 :(得分:1)
好的,问题似乎是缺少NewGlobalRef调用。这个版本有效:
#include <jni.h>
#include <pthread.h>
pthread_t thread;
jobject object;
JavaVM* jvm;
/*
Our thread function:
*/
void* run( void* );
extern "C" void Java_com_Program_Initialize( JNIEnv* jnv, jobject caller )
{
object = jnv->NewGlobalRef( caller );
jnv->GetJavaVM( &jvm );
pthread_create( &thread, NULL, run, NULL );
}
void* run( void* )
{
JNIEnv* jnv;
jvm->AttachCurrentThread( &jnv, NULL );
jnv->CallVoidMethod( object, jnv->GetMethodID( jnv->GetObjectClass( object ), "foo", "()V" ) );
jnv->DeleteGlobalRef( object );
jvm->DetachCurrentThread( );
return NULL;
}
答案 1 :(得分:0)
我建议您尝试找一种方法将调用发布到主线程。
由于整个过程来自&#34; AttachCurrentThread&#34; to&#34; DetachCurrentThread&#34;没有锁定,主线程可能会重新&#34; AttachCurrentThread&#34;,在某些情况下,在&#34;运行&#34;完了。因此仍然存在问题。