为什么在jni函数中全局变量为null?

时间:2019-05-23 12:27:39

标签: c++ java-native-interface

我正在尝试使用一个包含指向函数指针的变量。通过使用dlsym从JNI_OnLoad函数加载指针并调用它,但最终得到NULL POINTER DEREFERENCE,这表明我的SendCode在所有JNI函数中都是NULL(JNI_OnLoad除外) )。

我尝试使用全局指针SendCode在jni函数中再次初始化dlopen,但是由于这个问题,dlopen本身的全局指针始终为NULL。我还尝试过检查jni函数中的SendCode是否不为空,但是它使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 :(得分:0)

很可能是因为SendCode中的符号libapi.so本身为NULL或找不到:

  

...如果未找到该符号,则在指定的库或任何   由dlopen()自动加载的库   加载后,dlsym()返回NULL。 (由dlsym()执行的搜索为   广度优先通过这些库的依赖关系树。)   该符号的值实际上可以为NULL(以便返回NULL   来自dlsym()的内容不必表示错误),这是测试的正确方法   错误是调用dlerror()清除任何旧的错误条件,然后   调用dlsym(),然后再次调用dlerror()...

您可以通过使用虚拟函数初始化指针SendCode来轻松验证它(例如产生一些输出),然后按照代码流运行它。如果再次使用空指针取消引用获得段错误-您知道它在该赋值中(来自dlsym),则返回NULL。