ctypes加载有依赖的C共享库
在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
我也遇到过同样的问题。要解决这个问题,需要做两件事:
- 像其他用户说的那样,使用
RTLD_GLOBAL
- 你需要加载你的库所依赖的每一个库。所以如果
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
)来指定每一个这个库代码所用到的库。这样,原始共享库以这种方式引用的其他库也会自动加载。