Невозможно получить значение JNIEnv * в произвольном контексте

У меня проблема с NDK.

В моем методе JNI_OnLoad я кэширую указатель JavaVm, класс, который вызвал метод, и идентификатор метода, который я использую позже:

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved){
    JNIEnv *env;
    cachedJVM = jvm;
    if((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6)){
        LOG_ERROR("Could not get JNIEnv*");
        return JNI_ERR;
    }
    javaClass = (*env)->FindClass(env, "org/test/opensl/AudioProcessor");
    if(javaClass == NULL){
        LOG_ERROR("Could not get java class");
        return JNI_ERR;
    }
    javaCallbackMID = (*env)->GetMethodID(env, javaClass, "enqueueAudio", "([B)V");
    if(javaCallbackMID == NULL){
        LOG_ERROR("Could not get method identifier");
        return JNI_ERR;
    }
    return JNI_VERSION_1_6;
}

У меня есть небольшой служебный метод, определенный следующим образом, который должен дать мне указатель на JNIEnv:

JNIEnv* JNU_GetEnv(){
    JNIEnv* env;
    (*cachedJVM)->GetEnv(cachedJVM, (void**)&env, JNI_VERSION_1_6);
    return env;
}

И, наконец, У меня есть обратный вызов от OpenSL ES SLAndroidSimpleBufferQueueItf , который я хочу обрабатывать записанный звук из SLRecordItf :

void recorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context){
    SLresult result;
    JNIEnv* env;
    recorderContext* thisContext = (recorderContext*)context;
    env = JNU_GetEnv();
    if(env == NULL){
        LOG_ERROR("Could not get JNIEnv*");
        return;
    }
    jbyteArray data = (*env)->NewByteArray(env, MAX_PACKET_SIZE);
    if(data == NULL){
        LOG_ERROR("No memory could be allocated for buffer");
        return;
    }
    (*env)->SetByteArrayRegion(env, data, 0, MAX_PACKET_SIZE, recorderBuffer);
    (*env)->CallByteMethodA(env, thisContext->caller, javaCallbackMID, data);
    (*env)->DeleteLocalRef(env, data);
    result = (*bq)->Enqueue(bq, recorderBuffer,
                            RECORDER_FRAMES * sizeof(jbyte));
    checkError(result, "Unable to enqueue new buffer");
}

Где параметр контекста для метода обратного вызова содержит только ссылку на объект, который вызвал собственный метод. Это самоопределенная структура вроде этой:

typedef struct recorderContext{
    jobject caller;
} recorderContext;

Однако каждый раз, когда я пытаюсь запустить ее, я получаю сообщение об ошибке «Не удалось получить JNIEnv *» от метода обратного вызова.

Мой вопрос в основном сводится к следующему: почему я могу получить указатель на JNIEnv в методе JNI_OnLoad, но не в RecorderCallback, поскольку оба используют один и тот же указатель Java VM для получения JNIEnv?

Мне это нужно обратный вызов для передачи записанного аудио обратно на мой уровень Java для дальнейшей обработки ...

5
задан ThaMe90 13 May 2011 в 12:11
поделиться