Python调用C++动态库遇AttributeError:未定义symbol logarithm
问题:Python调用C++动态库报
AttributeError: undefined symbol: logarithm 问题详情
尝试用Python3调用C/C++编写的函数时触发报错:AttributeError: /src/libmi.so: undefined symbol: logarithm。该函数此前可正常被Python调用,当前已遗忘原配置方式。
完整异常栈:
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [1], in <cell line: 5>() 3 libname = os.path.abspath("/src/libmi.so") 4 mi = CDLL(libname) ----> 5 mi.logarithm.restype = c_double File /usr/local/lib/python3.8/ctypes/__init__.py:386, in CDLL.__getattr__(self, name) 384 if name.startswith('__') and name.endswith('__'): 385 raise AttributeError(name) --> 386 func = self.__getitem__(name) 387 setattr(self, name, func) 388 return func File /usr/local/lib/python3.8/ctypes/__init__.py:391, in CDLL.__getitem__(self, name_or_ordinal) 390 def __getitem__(self, name_or_ordinal): --> 391 func = self._FuncPtr((name_or_ordinal, self)) 392 if not isinstance(name_or_ordinal, int): 393 func.__name__ = name_or_ordinal AttributeError: /src/libmi.so: undefined symbol: logarithm
相关代码
C/C++函数代码
#ifdef __cplusplus extern "C" double logarithm(unsigned a) #else double logarithm(unsigned a) #endif { if (a != 0) { return log2(a); } else { return 0; } }
Python调用代码
import os from ctypes import * libname = os.path.abspath("/src/libmi.so") mi = CDLL(libname) mi.logarithm.restype = c_double
当前编译链接命令
g++ -fPIC -c $(python3.8-config --includes) -o mi.o mi.cpp g++ $(python3.8-config --ldflags) -lpython3.8 mi.o -o libmi.so
已完成排查
通过objdump检查动态库符号,确认logarithm符号存在:
root@5c574a48a4ce:/src# objdump -t libmi.so | grep logarithm 0000000000001225 g F .text 0000000000000034 logarithm
解决方案
问题出在动态库编译链接阶段的参数错误,修正编译命令即可:
第一步:编译生成目标文件(不变)
g++ -fPIC -c $(python3.8-config --includes) -o mi.o mi.cpp
第二步:链接生成正确的动态库
g++ -shared -fPIC mi.o -o libmi.so -lm
参数说明:
-shared:强制生成动态链接库,原命令未加此参数,实际生成的是可执行文件而非标准动态库,导致ctypes无法正确识别符号。-lm:链接数学库libm.so,因为代码中使用了log2()函数,该函数属于数学库,未链接会导致运行时符号缺失。- 移除不必要的Python库链接参数(
$(python3.8-config --ldflags)和-lpython3.8):此场景是Python主动调用动态库,而非动态库依赖Python,这些参数会干扰动态库的正常生成。
验证修复
重新编译后,再次用Python调用即可正常访问logarithm函数。
内容的提问来源于stack exchange,提问作者volkoshkursk
相关产品推荐
相关产品推荐

