Python中调用C动态库时提示undefined symbol错误如何解决?
有个奇怪的现象,
我要调用 c 里边的 add(),不知道是调用方法不对,还是怎么的。两种语言调用均提示函数找不到undefined symbol
如下代码。(函数是在libso.so中,libso.so依赖于libso1.so 、libso2.so)
但是!! 但是!!!
我命令行执行: nm -D libso.so
显示的函数名是这种:_ZN11add4InERKSs
我用这个看似乱码的函数名_ZN11add4InERKSs调用,居然调用成功了!!!而且用这个函数名 java 跟 python 均能调用成功,这是什么原因???求解释
import com.sun.jna.Library;
import com.sun.jna.Native;
public class Java_call_c {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)Native.loadLibrary("so1",CLibrary.class);
CLibrary INSTANCE1 = (CLibrary)Native.loadLibrary("so2",CLibrary.class);
CLibrary INSTANCE2 = (CLibrary)Native.loadLibrary("so",CLibrary.class);
int add();
}
public static void main(String[] args) {
System.out.println(CLibrary.INSTANCE2.add());
}
}
Python中调用C动态库时提示undefined symbol错误如何解决?
这个 so 是用 c++写的吧。
函数声明加上 extern “ C ”
遇到 undefined symbol 错误,通常是因为链接器在运行时找不到C库中声明的某个函数或变量。核心原因就两个:要么库没编译进去这个符号,要么Python加载器找错了地方。
最常见的情况是你的C库依赖了其他库,但没正确链接。比如你的 libfoo.so 用了 libbar.so 里的函数,但编译时没加 -lbar。
解决步骤:
-
用
nm或objdump查符号:# 查看你的库里有哪些符号(T表示已定义) nm -D your_library.so | grep your_missing_symbol # 或者 objdump -T your_library.so | grep your_missing_symbol如果找不到,说明编译时这个符号就没进去。
-
用
ldd看依赖:ldd your_library.so看看有没有
not found的依赖项。如果有,你得确保那些.so文件在系统的链接器搜索路径里(比如/usr/lib),或者用LD_LIBRARY_PATH环境变量加上路径。 -
检查编译命令: 确保编译时把所有需要的源文件和库都链上。比如:
gcc -shared -fPIC -o your_library.so your_code.c -lmissing_lib那个
-lmissing_lib经常被漏掉。 -
在Python里指定加载方式(治标不治本,但有时管用):
import ctypes # 让加载器解析所有未定义符号,直到运行时才去找 ctypes.cdll.LoadLibrary('your_library.so', mode=ctypes.RTLD_GLOBAL) # 然后再正常导入 from your_module import ...或者用
dlopen的RTLD_LAZY模式,但这不是根本解决办法。
根本解决: 回头检查你的C库编译过程,确保所有依赖都正确链接,该导出的符号都导出了(比如用 __attribute__((visibility("default"))) 或 -Wl,--export-dynamic)。
总结:检查编译链接依赖,确保符号被正确定义和导出。
加了
这种函数名符号是 C++的 ABI 样式。 加了 extern “C” 还是这种的话,说明没加对。
重新打包了一下可以了!!谢谢各位

