2013-08-05 7 views
7

Ich arbeite an einem Projekt, wo ich Java-Funktionen aus C++ - Code (mit JNI) aufrufen und ich habe ein Problem mit Multithreading. Ich möchte Java-Suchfunktion aufrufen und für jeden Anruf möchte ich einen separaten Thread erstellen. Ich habe ein Singleton MainClass und verschachtelte Query Klasse. Query Klasse wird von QThread geerbt. Code wie folgt aussiehtJNI Java aus C++ mit mehreren Threads aufrufen

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 
    } 

, Nun, wenn Sie diesen Code in einem einzigen Thread laufen - alles ist in Ordnung, aber wenn versuchen, über Code auszuführen - Multithreading verwenden, es verursacht Laufzeitfehler durch Meldung "Unhandled exception at 0x777715de in MyApp.exe: 0xC0000005: Access violation reading location 0x000000ac." wenn ich versuche, um die Methoden-ID zu erhalten. Ich habe es auch mit boost::thread versucht, aber das Ergebnis war das gleiche.

Warum schlägt es fehl, wenn ich es in einem separaten Thread mache, wenn im selben Thread alles in Ordnung ist? Irgendwelche Ideen?

Antwort

8

Scroll nach unten zu 'Montieren an der VM' in der JNI-Dokumentation:

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

Die JNI-Schnittstellenzeiger (JNIEnv) nur in dem aktuellen Thread gültig ist. Sollte ein anderer Thread auf die Java-VM zugreifen müssen, muss er zuerst AttachCurrentThread() aufrufen, um sich an die VM anzuhängen und einen JNI-Schnittstellenzeiger zu erhalten.

+0

Und ich werde ein Beispiel dafür http://stackoverflow.com/questions/12900695/how-to-obtain-jni-interface-pointer-jnienv-for-asynchronous-calls hinzufügen – nabroyan