10

私は、C++ コードから (JNI を使用して) Java 関数を呼び出すプロジェクトに取り組んでおり、マルチスレッドに関する問題があります。Java 検索関数を呼び出したいのですが、呼び出しごとに別のスレッドを作成したいと考えています。シングルトンMainClassとネストされたQueryクラスがあります。Queryクラスは から継承されQThreadます。コードは次のようになります

MainClass::MyQuery query("<some search query>");
query.LaunchQuery();


//functions of Query   
void MainClass::MyQuery::LaunchQuery() const
{
    this->start();
}

void MainClass::Query::run()
{
    const MainClass& mainClass = MainClass::GetInstance();
    const jclass& obj = mainClass.GetClass();
    JNIEnv& env = mainClass.GetJavaEnvironment();
    jmethodID methodId = env.GetMethodID(obj, "SearchQuery", "(Ljava/lang/String;)V"); //Run-time error

    if(methodId != 0)
    {
        //calling "SearchQuery" function
    }

"Unhandled exception at 0x777715de in MyApp.exe: 0xC0000005: Access violation reading location 0x000000ac."ここで、このコードをシングル スレッドで実行すると - すべて問題ありませんが、マルチスレッドを使用して上記のコードを実行しようとすると、メソッド ID を取得しようとすると、メッセージによって実行時エラーが発生します 。私も試しましboost::threadたが、結果は同じでした。

では、同じスレッドではすべて問題ないのに、別のスレッドで実行しているときに失敗するのはなぜですか? 何か案は?

4

1 に答える 1

12

JNI docs の「Attaching to the VM」まで下にスクロールします。

http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/invocation.html

JNI インターフェース ポインター (JNIEnv) は、現在のスレッドでのみ有効です。別のスレッドが Java VM にアクセスする必要がある場合は、最初に AttachCurrentThread() を呼び出して自分自身を VM に接続し、JNI インターフェース ポインターを取得する必要があります。

于 2013-08-05T11:19:03.370 に答える