使用Android NDK编译的程序运行时报未定义符号错误如何解决?
问题解决方法
问题根因
你遇到的未定义符号_ZTIN7android10IInterfaceE是C++ RTTI生成的android::IInterface类的typeinfo符号。Android 10官方编译系统固件时,libbinder默认携带-fno-rtti编译参数,关闭了RTTI生成,因此系统提取的libbinder.so中不会导出该typeinfo符号。而你自己编译jack2代码时默认开启了RTTI,因此生成的目标文件会引用该不存在的符号。
可行解决方案
- 方案1:关闭当前工程的RTTI编译(推荐)
binder框架本身不依赖RTTI运行,你只需要在jack2的编译配置中,给所有编译参数添加-fno-rtti,覆盖默认的RTTI开启配置,重新编译后就不会生成对IInterfacetypeinfo的引用,链接错误直接消失。
注意需要确保所有引用了binder头文件的源码(包括BnAndroidShm.cpp、BpAndroidShm.cpp)都使用该参数编译,避免出现编译参数不匹配的问题。 - 方案2:适配需要保留RTTI的场景
如果你的业务代码必须依赖RTTI功能无法关闭,可以在自己的工程代码中补充IInterface的虚析构函数实现,让typeinfo在你的libjackshm.so内部生成,不需要依赖libbinder的导出符号:
把这段代码加入你的任意一个编译单元即可,链接时会优先使用你本地生成的typeinfo符号。#include <binder/IInterface.h> namespace android { IInterface::~IInterface() = default; } - 临时绕过方案(不推荐)
如果你确认运行时不会用到dynamic_cast、typeid等依赖RTTI的功能,可以在链接参数中添加-Wl,--allow-shlib-undefined,忽略该未定义符号的链接错误。该方案存在运行时崩溃风险,仅建议调试阶段临时使用。
额外注意事项
- 编译时请使用API Level 29(对应Android 10)的NDK版本,不要使用更高API等级的NDK配置,避免头文件和系统库的ABI不匹配。
- 确保链接时优先使用你从设备提取的libbinder.so,不要链接NDK自带的libbinder.so,避免出现符号不匹配问题。
内容的提问来源于stack exchange,提问作者Pavel Samsonov
相关产品推荐
相关产品推荐

