Почему глобальные переменные равны нулю в функции jni? - PullRequest
0 голосов
/ 23 мая 2019

Я пытаюсь использовать переменную, которая содержит указатель на функцию.Указатель загружается из функции JNI_OnLoad с помощью dlsym и ее вызова, но в итоге я получил NULL POINTER DEREFERENCE, который показывает, что мой SendCode равен NULL внутри любой функции JNI (кроме JNI_OnLoad).

Я попытался снова инициировать SendCode в функции jni с глобальным указателем dlopen, но сам глобальный указатель dlopen всегда равен NULL из-за этой проблемы.Я также попытался проверить, не является ли SendCode ненулевым в функции jni, но он делает SendCode никогда не вызываемым, потому что он всегда равен нулю.

void(*SendCode)(int code);

extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
    JNIEnv* env;
    vm->GetEnv((void**)&env, JNI_VERSION_1_4);

    void* handle = dlopen("libapi.so", RTLD_NOW | RTLD_GLOBAL);
    if(handle != NULL)
    {
        SendCode = (void(*)(int))dlsym(handle, "SendCode"); 
        if(SendCode == NULL)
        {
            ALOGI("Error: SendCode is NULL!");
        }
    }
    return JNI_VERSION_1_4;
}

JNIEXPORT void JNICALL Java_com_myapp_MainActivity_onSendCode(JNIEnv*, jclass, jint code)
{
    SendCode(code);
}

1 Ответ

0 голосов
/ 23 мая 2019

скорее всего это потому, что символ SendCode в libapi.so либо сам по себе равен NULL, либо не найден:

... Если символ не найден, в указанной библиотеке или в любом другомиз библиотек, которые были автоматически загружены dlopen () при загрузке этой библиотеки, dlsym () возвращает NULL.(Поиск, выполняемый dlsym (), сначала идет по дереву зависимостей этих библиотек.) Поскольку значение символа может фактически быть NULL (так что возвращаемое NULL из dlsym () не должно указывать на ошибку), правильный путьпроверить наличие ошибки - это вызвать dlerror (), чтобы очистить все старые условия ошибки, затем вызвать dlsym (), а затем снова вызвать dlerror () ...

, вы можете легко проверить это с помощью initиспользуя указатель SendCode с помощью фиктивной функции (например, производя некоторый вывод), а затем запускайте его согласно потоку кода.Если вы снова получаете segfault с разыменованием нулевого указателя - вы знаете, что оно находится в этом назначении (с dlsym), возвращается NULL.

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