@vadim0872

Потоки при разработке android ndk?

Разрабатываю приложение под android с использованием ndk. В книге прочел, что, если создан поток в низкоуровневой части приложения, этот поток надо присоединить к JVM(понятно что в андроид Davlik, но не суть), чтобы можно было обращаться к JVM через указатель, соответственно нужно вызвать метод AttachCurrentThread(Jnienv *env) и соответственно с помощью этой функции получить указатель на JVM.
Для этих целей я написал два метода, которые присоединяют поток, если он не присоединен, а после отсоединяют.
JavaVM *javaVM;

boolean GetJniEnvAndAttach(JNIEnv *jniEnv){

    int resault = (javaVM->GetEnv((void **) &jniEnv, JNI_VERSION_1_6));
    if (resault == JNI_EDETACHED){
        if (javaVM->AttachCurrentThread(&jniEnv,0) == JNI_OK){
            LOGI("Thread attach to JVM");
            return true;
        }
    } else {
        LOGI("Thread wasn`t attach");
        }
        return false;
    }
}

void Detach(boolean isAttach){
    if (isAttach){
        javaVM->DetachCurrentThread();
    }
}

Перед кодом который использует указатель на jvm, вызывается: GetJniEnvAndAttach, а по окончанию Detach.
JavaVM инициализируется при запуске приложения:
JNIEXPORT jint JNICALL JNI_OnLoad(
        JNIEnv *env) {

    JavaVM *jmv = NULL;
    env->GetJavaVM(&jmv);
    javaVM = jmv;
    return JNI_OK;

}


Суть вопроса в том, что если я создаю низкоуровневый поток, то все прикрепляется и открепляется как надо, а если я вызываю эти функции из потока созданного jvm все падает с ошибкой: "A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 12345"
В чём проблема?
  • Вопрос задан
  • 234 просмотра
Решения вопроса 1
@vadim0872 Автор вопроса
Возможно кому-нибудь будет интересно, но я разобрался в проблеме.
Оказалось, что я не очень дружу с указателями в си, в качестве аргумента нужно было передавать не просто указатель на jnienv, а указатель на указатель, но и это не совсем заработало, поэтому я внутрь метода GetJniEnvAndAttach, добавил локальную переменную localenv* Jnienv; которую и использовал дальше внутри функции, а перед возвратом из функции присваивал указателю переданному в аргументе: &jnienv = localenv;
boolean GetJniEnvAndAttach(JNIEnv **jniEnv){

    JNIEnv *localEnv = NULL;

    if (javaVM->GetEnv((void **) &localEnv, JNI_VERSION_1_6) == JNI_EDETACHED){
        if (javaVM->AttachCurrentThread(&localEnv,0) == JNI_OK){
            *jniEnv = localEnv;
            LOGI("Thread attach to JVM");
            return true;
        }
    } else {
        *jniEnv = localEnv;
        LOGI("Thread wasn`t attach");

        return false;
    }
    return false;
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы