NDK编译库运行时报dlopen failed: cannot locate symbol "__exidx_end" 解决办法

解决NDK编译库加载错误
本文介绍了解决使用NDK编译的库在运行时出现找不到符号__exidx_end的问题。通过在Android.mk文件中添加LOCAL_LDFLAGS+=-fuse-ld=bfd来解决该问题。
AI助手已提取文章相关产品:

当用NDK编译的库在运行加载时报如下错:

dlopen("/data/data/xxx.xxx.xxx/lib/libxxx.so") failed: dlopen failed: cannot locate symbol "__exidx_end" referenced by "libxxx.so"...

解决办法如下:

在你报错的库libxxx.so的编译脚本Android.mk请加上:LOCAL_LDFLAGS += -fuse-ld=bfd

您可能感兴趣的与本文相关内容

<think> 嗯,用户这次遇到了一个Native加载错误:"java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol '__sfp_handle_exceptions'",这已经是第三次提出类似问题了,看来比较棘手。用户引用了三个站内案例,但核心问题集中在C++符号缺失,特别是标准符号。 注意到用户提到了vlcjni,这是vlc播放器的Java绑定。深层需求应该是想在Android集成VLC播放功能。错误中的"__sfp_handle_exceptions"很关键——这是glibc中处理浮点异常的底层符号,通常出现在NDK编译环境混乱时。 结合引用[2]提到的NDK版本兼容性问题,以及引用[3]的调试选项干扰,解决方案应该聚焦在: 1. 环境一致性:检查NDK版本与项目targetSdkVersion是否匹配。vlcjni官方文档要求NDK r21d,而用户项目可能用了更高版本 2. 符号冲突:__sfp_handle_exceptions属于libandroid_support,在NDK r18后弃用,需要确认vlcjni是否使用了旧ABI 3. 动态链接:分析libvlcjni.so的依赖链,可能是间接依赖的静态缺失该符号 用户可能已经尝试过常规方法,需要更底层的解决思路。考虑到vlcjni的特殊性,建议重点排查: - 是否混用了不同C++运行时(gnustl vs libc++) - 编译vlcjni时是否启用了异常处理(-fexceptions) - AndroidManifest中android:extractNativeLibs的设置 最后要提醒用户:这类错误通常需要重建整个native环境,单纯配置调整可能不够彻底。如果时间允许,最好用Docker创建纯净编译环境。 </think> 根据错误信息 `java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__sfp_handle_exceptions"`,结合站内引用和开发经验,以下是系统性的解决方案: --- ### **问题根源分析** 1. **符号缺失**:Android 运行时找不到 `__sfp_handle_exceptions`(标准C中处理浮点异常的符号) 2. **编译环境不匹配**: - NDK 版本与项目 `compileSdkVersion`/`targetSdkVersion` 不兼容 [^2] - 文件依赖了与当前设备ABI不兼容的C++运行时(如 `libc++_shared.so` 未正确打包) 3. **链接冲突**:多个文件使用了不同版本的C++标准(常见于混合编译) --- ### **解决方案步骤** #### 1. **统一NDK与SDK版本** - 在 `build.gradle` 中明确指定兼容的NDK版本: ```gradle android { compileSdkVersion 30 ndkVersion "21.4.7075529" // 推荐使用LTS版本 } ``` - **验证**:检查 `local.properties` 中 `ndk.dir` 路径是否指向一致版本 #### 2. **添加C++运行时共享** - 在 `CMakeLists.txt` 中动态链接 `libc++_shared.so`: ```cmake add_library(native-lib SHARED ...) target_link_libraries(native-lib android log c++_shared # 关键:强制使用共享C++运行时 ) ``` - **打包验证**:编译后检查APK的 `lib/arm64-v8a` 是否包含 `libc++_shared.so` #### 3. **检查ABI过滤与依赖冲突** - 在 `build.gradle` 中限定支持的ABI: ```gradle android { defaultConfig { ndk { abiFilters 'arm64-v8a', 'armeabi-v7a' } // 按需选择 } } ``` - **排查冲突**:运行 `nm -D libvlcjni.so | grep __sfp_handle_exceptions` 确认符号是否存在 #### 4. **禁用高级分析工具(针对旧设备)** - 关闭 Android Studio 的冲突选项 [^3]: ``` Run → Edit Configurations → Profiling → 取消勾选 "Enable advanced profiling" ``` #### 5. **重建原生依赖** ```bash cd project_root ./gradlew clean rm -rf .cxx/ # 删除CMake缓存 ./gradlew assembleDebug --refresh-dependencies ``` --- ### **预防措施** 1. **符号可见性控制**:在C++代码中隐藏内部符号: ```cpp __attribute__ ((visibility ("hidden"))) void internal_func(); ``` 2. **NDK版本矩阵**: | NDK版本 | 兼容SDK版本 | 备注 | |---------|------------|-----------------------| | 21.x | 28-31 | 推荐LTS版本 | | 25.x | 32+ | 需启用 `c++_shared` | 3. **静态链接替代方案**(若可行): ```cmake target_link_libraries(native-lib libvlcjni.a) ``` > 若仍失败,建议使用 `addr2line` 定位符号来源: > `aarch64-linux-android-addr2line -e libvlcjni.so [符号地址]` --- ### 相关问题 1. 如何检查 Android NDK 版本与项目 SDK 的兼容性? 2. 动态链接 `libc++_shared.so` 与静态链接有何性能差异? 3. Android 开发中如何避免 C++ 标准的 ABI 冲突? 4. 为什么 `__sfp_handle_exceptions` 在较新的 NDK 中会被移除? [^1]: 引用自用户提供的堆栈错误信息 [^2]: NDK 版本兼容性原则 [^3]: Android Studio 高级分析工具冲突场景
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值