为何后续dlopen加载的.so文件无法获取所需符号?
问题:Android中dlopen加载全局符号后依赖库仍无法找到符号
我正尝试解决一个Android动态库命名空间相关的问题,方案是把所有Python相关代码移到独立的.so文件,通过自定义加载器加载运行。原本以为用dlopen指定RTLD_NOW|RTLD_GLOBAL参数会把所有符号加载到默认命名空间,从而绕过命名空间问题,但实际遇到了异常。
以下是JNI中的加载器代码:
extern "C" JNIEXPORT void JNICALL Java_com_example_app_NativeLoader_load( JNIEnv* env, jobject /* this */, jstring jLibraryPath) { const char *libraryPath = env->GetStringUTFChars(jLibraryPath, NULL); void *handle = dlopen(libraryPath, RTLD_NOW|RTLD_GLOBAL); if (handle == nullptr) { LOGD("load %s failed: %s", libraryPath, dlerror()); goto exit; } // 库加载成功 // 接下来应加载入口函数并运行 // 这里做个测试: void *sym = dlsym(handle, "PyExc_SystemError"); ///< 此操作可行 void *handle_2 = dlopen("/some/path/to/_csv.cpython-310.so", RTLD_NOW); if (handle_2 == nullptr) { // !!! 意外进入此分支 LOGD("load _csv.cpython-310.so failed: %s", dlerror()); } exit: env->ReleaseStringUTFChars(jLibraryPath, libraryPath); }
测试确认PyExc_SystemError存在于主库中,但加载_csv.cpython-310.so时却报错:
03:57:17.744 3102 3102 D example: load /data/app/com.example.app-v4JTCukKIPJdXmBSnDMO6A==/base.apk!/lib/x86_64/_csv.cpython-310.so failed: dlopen failed: cannot locate symbol "PyExc_SystemError" referenced by "/data/app/com.example.app-v4JTCukKIPJdXmBSnDMO6A==/base.apk!/lib/x86_64/_csv.cpython-310.so"
运行环境为Android 9.0/10.0/11.0,NDK版本为r25。请问为何这些符号无法被访问?
内容的提问来源于stack exchange,提问作者Holmes Conan
相关产品推荐
相关产品推荐

