Python中调用C动态库时提示undefined symbol错误如何解决?

有个奇怪的现象, 我要调用 c 里边的 add(),不知道是调用方法不对,还是怎么的。两种语言调用均提示函数找不到undefined symbol

如下代码。(函数是在libso.so中,libso.so依赖于libso1.solibso2.so

但是!! 但是!!!

我命令行执行: nm -D libso.so 显示的函数名是这种:_ZN11add4InERKSs

我用这个看似乱码的函数名_ZN11add4InERKSs调用,居然调用成功了!!!而且用这个函数名 javapython 均能调用成功,这是什么原因???求解释

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错误如何解决?

6 回复

这个 so 是用 c++写的吧。
函数声明加上 extern “ C ”


遇到 undefined symbol 错误,通常是因为链接器在运行时找不到C库中声明的某个函数或变量。核心原因就两个:要么库没编译进去这个符号,要么Python加载器找错了地方。

最常见的情况是你的C库依赖了其他库,但没正确链接。比如你的 libfoo.so 用了 libbar.so 里的函数,但编译时没加 -lbar

解决步骤:

  1. nmobjdump 查符号:

    # 查看你的库里有哪些符号(T表示已定义)
    nm -D your_library.so | grep your_missing_symbol
    # 或者
    objdump -T your_library.so | grep your_missing_symbol
    

    如果找不到,说明编译时这个符号就没进去。

  2. ldd 看依赖:

    ldd your_library.so
    

    看看有没有 not found 的依赖项。如果有,你得确保那些 .so 文件在系统的链接器搜索路径里(比如 /usr/lib),或者用 LD_LIBRARY_PATH 环境变量加上路径。

  3. 检查编译命令: 确保编译时把所有需要的源文件和库都链上。比如:

    gcc -shared -fPIC -o your_library.so your_code.c -lmissing_lib
    

    那个 -lmissing_lib 经常被漏掉。

  4. 在Python里指定加载方式(治标不治本,但有时管用):

    import ctypes
    # 让加载器解析所有未定义符号,直到运行时才去找
    ctypes.cdll.LoadLibrary('your_library.so', mode=ctypes.RTLD_GLOBAL)
    # 然后再正常导入
    from your_module import ...
    

    或者用 dlopenRTLD_LAZY 模式,但这不是根本解决办法。

根本解决: 回头检查你的C库编译过程,确保所有依赖都正确链接,该导出的符号都导出了(比如用 __attribute__((visibility("default")))-Wl,--export-dynamic)。

总结:检查编译链接依赖,确保符号被正确定义和导出。

这种函数名符号是 C++的 ABI 样式。 加了 extern “C” 还是这种的话,说明没加对。

重新打包了一下可以了!!谢谢各位

回到顶部