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

PyBind11封装外部.so库后Python导入报未定义符号问题求助

问题:PyBind11封装外部库后导入出现未定义符号错误

错误现象

导入封装模块时触发以下错误:

/home/user/dev/external/Python/PyBind_Module/external_python.cpython-310-x86_64-linux-gnu.so: undefined symbol: <FUNCTION>
  File "/home/user/dev/external/Python/pybind_test.py", line 3, in <module>
    import external_wrapper as exw
ImportError: /home/user/dev/external/Python/PyBind_Module/external_python.cpython-310-x86_64-linux-gnu.so: undefined symbol: <FUNCTION>

执行nm -gD命令确认目标函数已在外部库的导出符号列表中:

nm -gD /usr/lib/libexternal.so | grep 'FUNCTION'
00000000000170c0 T FUNCTION
0000000000018ff0 T FUNCTIONd

当前使用的setup.py代码

from pathlib import Path

from pybind11.setup_helpers import build_ext
from pybind11.setup_helpers import Pybind11Extension
from setuptools import setup

example_module = Pybind11Extension(
    "external_python",
    sources=[str(fname) for fname in Path("src").glob("*.cpp")],
    include_dirs=["include", "."],
    extra_compile_args=["-O3"],
    libraries=["/usr/lib/libexternal.so"],
    library_dirs=["/usr/lib"]
)

setup(
    name="external_module",
    version=1.0,
    description="C++ wrapper around the external library",
    ext_modules=[example_module],
    cmdclass={"build_ext": build_ext},
)

解决方案

1. 修正setup.py的链接参数写法

libraries参数只需传入库的名称(去掉前缀lib和后缀.so),不需要完整路径。修改后:

example_module = Pybind11Extension(
    "external_python",
    sources=[str(fname) for fname in Path("src").glob("*.cpp")],
    include_dirs=["include", "."],
    extra_compile_args=["-O3"],
    libraries=["external"]  # 仅保留库名
)

注:/usr/lib是系统默认的库搜索路径,因此可以省略library_dirs参数。

2. 添加运行时库搜索路径(可选)

如果编译后的模块仍无法在运行时找到依赖库,可通过extra_link_args添加-rpath参数,硬编码库的搜索路径:

example_module = Pybind11Extension(
    "external_python",
    sources=[str(fname) for fname in Path("src").glob("*.cpp")],
    include_dirs=["include", "."],
    extra_compile_args=["-O3"],
    libraries=["external"],
    extra_link_args=["-Wl,-rpath=/usr/lib"]  # 指定运行时库路径
)

3. 验证链接状态

编译完成后,用ldd命令检查生成的模块是否正确链接到目标库:

ldd /home/user/dev/external/Python/PyBind_Module/external_python.cpython-310-x86_64-linux-gnu.so

若输出中显示libexternal.so => /usr/lib/libexternal.so,说明链接正常。

4. 检查C++名字修饰问题

如果外部库是C编写的,需确保封装代码中用extern "C"声明函数,避免C名字修饰导致符号不匹配:

#ifdef __cplusplus
extern "C" {
#endif

// 外部库函数声明
void FUNCTION();

#ifdef __cplusplus
}
#endif

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 01:07:39