I'm working on a project, where I call Java functions from C++ code (using JNI) and I have a problem about multithreading. I want to call Java searching function and for each call I want to make a separate thread. I have a singleton MainClass
and nested Query
class. Query
class is inherited from QThread
. Code looks like this
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
}
Now, if run this code in a single thread - everything is fine, but if try to run above code - using multithreading, it causes run-time error by message
"Unhandled exception at 0x777715de in MyApp.exe: 0xC0000005: Access violation reading location 0x000000ac."
when I try to get method id. I've tried also with boost::thread
but result was the same.
So why it fails when I'm doing it in a separate thread, when in the same thread everything is fine? Any ideas?
Scroll down to 'Attaching to the VM' in the JNI docs :
http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/invocation.html
The JNI interface pointer (JNIEnv) is valid only in the current thread. Should another thread need to access the Java VM, it must first call AttachCurrentThread() to attach itself to the VM and obtain a JNI interface pointer.
User contributions licensed under CC BY-SA 3.0