我正在尝试使用一个包含指向函数指针的变量。通过使用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);
}
答案 0 :(得分:0)
很可能是因为SendCode
中的符号libapi.so
本身为NULL或找不到:
...如果未找到该符号,则在指定的库或任何 由dlopen()自动加载的库 加载后,dlsym()返回NULL。 (由dlsym()执行的搜索为 广度优先通过这些库的依赖关系树。) 该符号的值实际上可以为NULL(以便返回NULL 来自dlsym()的内容不必表示错误),这是测试的正确方法 错误是调用dlerror()清除任何旧的错误条件,然后 调用dlsym(),然后再次调用dlerror()...
您可以通过使用虚拟函数初始化指针SendCode
来轻松验证它(例如产生一些输出),然后按照代码流运行它。如果再次使用空指针取消引用获得段错误-您知道它在该赋值中(来自dlsym
),则返回NULL。