1

なんらかの理由で、スレッドから Java オブジェクト (プログラム全体で保持されます) にアクセスしようとすると、プログラムがクラッシュします。問題を示すために、煮詰めた例を次に示します。

#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;
}

何がうまくいかないかについてのアイデアはありますか?

4

2 に答える 2

2

さて、問題は 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;
}
于 2013-09-19T15:13:16.093 に答える
0

呼び出しをメインスレッドに投稿する方法を見つけることをお勧めします。

「AttachCurrentThread」から「DetachCurrentThread」までのプロセス全体がロックされていないため、「実行」が完了する前にメインスレッドが「AttachCurrentThread」を再実行する場合があります。したがって、まだ問題があるでしょう。

于 2014-11-19T15:11:09.883 に答える