python ctypes 加载具有依赖项的 ac 共享库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2327344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ctypes loading a c shared library that has dependencies
提问by zoobert
On Linux, I have a c shared library that depends on other libs. LD_LIBRARY_PATH is properly set to allow the linker to load all the libraries. When I do:
在 Linux 上,我有一个依赖于其他库的 ac 共享库。LD_LIBRARY_PATH 已正确设置以允许链接器加载所有库。当我做:
libgidcwf = ctypes.cdll.LoadLibrary(libidcwf_path)
I get the following error:
我收到以下错误:
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
It seems that LD_LIBRARY_PATH has no effect here. Is there a way to have these dependency library "loadable" ?
LD_LIBRARY_PATH 在这里似乎没有影响。有没有办法让这些依赖库“可加载”?
Thanks in advance for the help.
在此先感谢您的帮助。
回答by Geoff Reedy
It would seem that libwav.so does not declare it's dependency on the library defining ODBCGeneralQuery. Try running ldd path-to-my-lib/libwav.so
and see if there's something missing. If this is a shared library that you are building you should add -llibname
to the linking command (the one that is something like gcc -shared -o libwav.so a.o b.o c.o
) for each library that the library's code uses. Any other libraries referenced by the original shared library in this way should automatically be loaded as well.
libwav.so 似乎没有声明它依赖于定义 ODBCGeneralQuery 的库。尝试运行ldd path-to-my-lib/libwav.so
,看看是否缺少某些东西。如果这是您正在构建的共享库,您应该为库代码使用的每个库添加-llibname
链接命令(类似于 的命令gcc -shared -o libwav.so a.o b.o c.o
)。原始共享库以这种方式引用的任何其他库也应该自动加载。
回答by rokuingh
You should use RTLD_GLOBAL. I have a mixed platform system, so my code looks something like this:
您应该使用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)
回答by Luigi
When you compile the shared object, be sure to put all the -lsomething
at the end of the string command. For me it solved the problem.
编译共享对象时,请务必将所有的-lsomething
放在字符串命令的末尾。对我来说它解决了这个问题。
回答by Beni Lev
I had the same problem. Two things were required in order to solve it:
我有同样的问题。为了解决这个问题,需要做两件事:
- use the
RTLD_GLOBAL
as other users said - You need to load every library that is used by your library. So if
ODBCGeneralQuery
is defined in lets saylibIDCodbc
, you need first run this line:
- 使用
RTLD_GLOBAL
其他用户所说的 - 您需要加载您的库使用的每个库。因此,如果
ODBCGeneralQuery
在让我们说定义libIDCodbc
,你需要先运行这一行:
ctypes.CDLL("libIDCodbc.so", mode = ctypes.RTLD_GLOBAL)
ctypes.CDLL("libIDCodbc.so", mode = ctypes.RTLD_GLOBAL)
回答by Walter Nissen
I found I had to use RTLD_LAZY
due to an undefined symbol that was not linked because it was not being used. Since there is no ctypes.RTLD_LAZY
in my ctypes, I had to use:
我发现我必须使用RTLD_LAZY
一个未定义的符号,因为它没有被使用而没有被链接。由于ctypes.RTLD_LAZY
我的 ctypes 中没有,我不得不使用:
ctypes.CDLL(libidcwf_path, mode=1)
I found this mode by inspecting /usr/include/bits/dlfcn.h
which is probably not standard. Hat tip to this 2006 threadon the ctypes mailing list.
我通过检查/usr/include/bits/dlfcn.h
可能不标准的方式发现了这种模式。对 ctypes 邮件列表上的这个 2006主题的帽子提示。