You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu20.04下pybind11调用C++库出现已定义共享库符号未找到错误

问题背景

在Ubuntu 20.04系统上开发通过pybind11封装、供Python 3.8调用的C++代码,运行时出现如下报错:

Traceback (most recent call last):
snip...
ImportError: <full-path>/<lib-name-A>.so: undefined symbol: <mangled symbol name>

已排查确认两点:

  • 执行ldd <lib-name-A.so路径>,输出显示该符号所属的依赖库libB的绝对路径无异常
  • 执行nm -s --demangle <libB路径>,可以看到该符号定义在text段,且其修饰名(mangled name)与报错信息中的完全一致
可能的故障原因
  • 符号可见性配置问题
    C++编译时默认符号隐藏,若libB编译时开启了-fvisibility=hidden参数,且该符号没有显式添加__attribute__((visibility("default")))导出标记,即使本地符号表(nm默认输出)可以查到该符号,动态链接器也无法识别到该导出符号。可执行nm -D <libB路径>查看动态符号表,若该表中无对应符号即可确认是此问题。
  • 编译时链接参数顺序错误
    ld链接器按从左到右的顺序处理链接参数,仅会加载当前已出现的未定义符号对应的库内容。如果编译libA时-lB参数放在了依赖该符号的目标文件之前,处理-lB时还没解析到libA的未定义符号,就会跳过加载libB的对应符号,最终导致libA的符号未定义。需调整参数顺序,将-lB放在所有依赖它的目标文件之后。
  • ABI不兼容
    libA和libB编译时使用了不一致的ABI相关编译参数,比如一个开启了_GLIBCXX_USE_CXX11_ABI=0使用旧版C字符串/列表ABI,另一个使用默认的新版ABI,或使用了不同的C标准、异常/RTTI开关等,即使符号修饰名完全一致,也会出现链接失败问题。
  • 运行时加载的libB版本不匹配
    ldd输出的是编译时记录的依赖路径,运行时动态链接器可能因为LD_LIBRARY_PATH优先级、ld.so.cache缓存、Pythonsys.path下存在同名libB等原因,加载了另一个版本的libB。可在执行Python脚本前添加LD_DEBUG=libs环境变量,查看实际加载的libB路径,与你校验的libB路径对比确认。
  • 符号版本不匹配
    若libB存在多版本符号定义,libA编译时链接的libB符号版本与运行时加载的libB符号版本不一致,即使符号名相同也会报错。可执行objdump -x <libA路径> | grep NEEDED查看libA依赖的libB版本,与运行时加载的版本做对比。

内容的提问来源于stack exchange,提问作者Uri Raz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:45:03