2012-02-03 3 views
2

Я пытаюсь сделать следующее (не уверен, если я что-то отсутствует, или если это не представляется возможным):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] ...

+0

вы вызываете AttachCurrentThread и используете возвращаемый env указатель, не так ли? – mcnicholls

+0

@mcnicholls: да. После этого я делаю GetObjectClass, используя экземпляр jobject, который я помню из исходного потока, который я также использую, когда я делаю env-> CallVoidMehtod (jobj, ...), где env - это то, что было возвращено при вызове AttachCurrentThread. – Mark

+0

Можете ли вы показать больше кода? То, что вы делаете, звучит правильно; глобальная ссылка может использоваться любым потоком, пока вы ее не удалите. –

ответ

3

Вы, кажется, не обращая внимания на результат NewGlobalRef Вы должны использовать свой результат в другом потоке вместо оригинального jobj

..
+0

Вот и все. Спасибо! – Mark

Смежные вопросы