JNI, многопоточность и вызов методов - PullRequest
3 голосов
/ 03 февраля 2012

Я пытаюсь сделать следующее (не уверен, что я что-то упустил или это невозможно):

У меня есть класс Java (в данном случае сервлет), который вызывает собственный метод.

В этом родном методе я создаю новый поток, и в этом потоке я хотел бы вызвать метод для этого объекта Java. Это вообще возможно?

То, что я пробовал в собственном методе, который называется (оригинальный поток), - это запоминание экземпляра JavaVM, чтобы позже я мог присоединить к нему другой поток (кажется, работает) и сделать ссылку NewGlobal для задания :

    JavaVM *vm;
env->GetJavaVM(&vm);

env->NewGlobalRef(jobj)

Чего я не знаю, так это как получить объект задания в другом потоке. Если я просто передаю его, то происходит сбой виртуальной машины, я полагаю, из-за нелегального доступа к потоку. Если бы я создал новый объект для класса, у меня не было бы именно того объекта, который мне нужен.

Есть идеи?

Спасибо, Mark

НЕКОТОРЫЕ ДОПОЛНИТЕЛЬНЫЕ КОДЫ (имена методов и т. Д. Скрыты):

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] ...

1 Ответ

3 голосов
/ 03 февраля 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...