Как реализовать обратный вызов в Java из C с использованием JNI?

1

Я использую JNI в своем Java-коде для вызова собственного кода C. Это прекрасно работает, и я делаю некоторую обработку в коде C. Код C регистрирует прослушиватель событий, поэтому я уведомляюсь каждый раз, когда новый результат готов в части C.

Теперь я хочу вернуть результаты в код Java следующим образом:

void notifyGazeEvent()
{
    jclass cls = (*env)->GetObjectClass(env, obj);
    jmethodID mid = (*env)->GetMethodID(env, cls, "newGazeEvent", "(I)V");
    if (mid == 0)
    {
        return; 
    }
    printf("In C, about to enter Java");
    (*env)->CallVoidMethod(env, obj, mid, 1);
}

Теперь проблема заключается в следующем: я не знаю, откуда взять объект JNIEnv и объект jObject. Это передается, когда я сначала вызываю код C:

JNIEXPORT void JNICALL
Java_a_b_C_doCalculation(JNIEnv *env, jobject obj)
{
// here I register all the handlers etc, 
}

Но я не знаю, как я могу передать ссылки до моего метода, который выполняет обратный вызов Java.

Теги:
jni

1 ответ

1

Чтобы сохранить jobject obj за пределами функции Java_a_b_C_doCalculation, вам нужно создать глобальную ссылку, так как все объекты (JNIEnv также) перестают действовать после возвращения функции. Глобальную ссылку можно легко создать с помощью NewGlobalRef.

Указатель JNIEnv не может быть сохранен таким образом, также если поток, который вызывает notifyGazeEvent() был создан в C, вы должны сначала связать поток с JVM. Сохранить JavaVM *vm указатель из JNI_OnLoad, и либо optain в JNIEnv с GetEnv или присоединить вновь созданную нить AttachCurrentThread (AsDaemon).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню