Я пытаюсь сделать следующее (не уверен, если я что-то отсутствует, или если это не представляется возможным):JNI, Mulithreading и методы, требующие
У меня есть класс Java (в данном конкретном случае Servlet), который вызывает собственный метод.
В этом нативном методе я создаю новый поток, и в этом потоке я хотел бы вызвать метод на этом объекте Java. Возможно ли это?
То, что я пробовал в собственном методе, который называется (исходный поток), - это помнить экземпляр JavaVM, так что я могу позже подключить к нему другой поток (как представляется, работает) и сделать refring NewGlobal для jobject:
JavaVM *vm;
env->GetJavaVM(&vm);
env->NewGlobalRef(jobj)
То, что я не знаю, - как получить задание в другой теме. Если я просто передаю его, VM сбой, я предполагаю из-за незаконного доступа к потоку. Если я создам новый объект для класса, у меня не будет точного объекта, который мне нужен.
Любые идеи?
Спасибо, Марку
дополнительный код (имена методов и т.д. затемняется):
The method that is called from the servlet:
JNIEXPORT jstring JNICALL ABC (JNIEnv *env, jobject jobj, some more arguments
{
JavaVM *vm;
env->GetJavaVM(&vm);
env->NewGlobalRef(jobj);
// spawning new thread (I'm using boost libraries)
boost::thread t = boost::thread(boost::bind(&XYZ::DEF, instance of XYZ, vm, &jobj);
...
}
void XYZ::DEF(JavaVM* vm, jobject* jobj)
{
JNIEnv* env;
vm->GetEnv((void**)&env, JNI_VERSION_1_2);
vm->AttachCurrentThread((void**)&env, NULL);
... then eventually calling another method, but still the same thread, where I'm doing this:
jobject bb = env->NewDirectByteBuffer(...,...); // this crashed when I just used the env from the original thread, seems to work since I'm attaching the second thread to the VM.
// it crashes somewhere during the following code:
jclass cls = env->GetObjectClass(jobj);
jmethodID mid = env->GetMethodID(cls, "callback", "(I)V");
env->CallVoidMethod(jobj, mid, 13);
Катастрофа производит что-то вроде этого «фатальная ошибка была обнаружена в JRE ... Проблемный рама: V [libjvm.so + 0x3e9220] ...
вы вызываете AttachCurrentThread и используете возвращаемый env указатель, не так ли? – mcnicholls
@mcnicholls: да. После этого я делаю GetObjectClass, используя экземпляр jobject, который я помню из исходного потока, который я также использую, когда я делаю env-> CallVoidMehtod (jobj, ...), где env - это то, что было возвращено при вызове AttachCurrentThread. – Mark
Можете ли вы показать больше кода? То, что вы делаете, звучит правильно; глобальная ссылка может использоваться любым потоком, пока вы ее не удалите. –