ctypes加载有依赖的C共享库

28 投票
6 回答
26223 浏览
提问于 2025-04-15 19:40

在Linux系统上,我有一个C语言的共享库,它依赖于其他一些库。LD_LIBRARY_PATH这个环境变量已经正确设置,可以让链接器加载所有需要的库。当我执行以下命令时:

libgidcwf    = ctypes.cdll.LoadLibrary(libidcwf_path)

我遇到了以下错误:

Traceback (most recent call last):
  File "libwfm_test.py", line 12, in <module>
    libgidcwf    = ctypes.cdll.LoadLibrary(libidcwf_path)
  File "/usr/lib/python2.5/ctypes/__init__.py", line 431, in LoadLibrary
    return self._dlltype(name)
  File "/usr/lib/python2.5/ctypes/__init__.py", line 348, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: path-to-my-lib/libwav.so: undefined symbol: ODBCGeneralQuery

看起来LD_LIBRARY_PATH在这里没有起作用。有没有办法让这些依赖的库能够被加载呢?

提前感谢大家的帮助。

6 个回答

8

我也遇到过同样的问题。要解决这个问题,需要做两件事:

  1. 像其他用户说的那样,使用 RTLD_GLOBAL
  2. 你需要加载你的库所依赖的每一个库。所以如果 ODBCGeneralQuery 是在比如说 libIDCodbc 中定义的,你首先需要运行这一行:

ctypes.CDLL("libIDCodbc.so", mode = ctypes.RTLD_GLOBAL)

8

你应该使用 RTLD_GLOBAL。我有一个混合平台的系统,所以我的代码大概是这样的:

import numpy, ctypes
try:
  if "Linux" in esmfos:
    _ESMF = ctypes.CDLL(libsdir+'/libesmf.so', mode=ctypes.RTLD_GLOBAL)
  else:
    _ESMF = numpy.ctypeslib.load_library('libesmf', libsdir)
except:
  traceback.print_exc(file=sys.stdout)
  sys.exit(ESMP_ERROR_SHAREDLIB)
18

看起来libwav.so这个库没有声明它依赖于定义ODBCGeneralQuery的那个库。你可以试着运行一下 ldd path-to-my-lib/libwav.so,看看有没有什么缺失的东西。如果你正在构建的是一个共享库,你应该在链接命令中加上 -llibname(这个命令大概是 gcc -shared -o libwav.so a.o b.o c.o)来指定每一个这个库代码所用到的库。这样,原始共享库以这种方式引用的其他库也会自动加载。

撰写回答