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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-04 00:22:45  来源:igfitidea点击:

ctypes loading a c shared library that has dependencies

pythonlinuxctypes

提问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.soand see if there's something missing. If this is a shared library that you are building you should add -llibnameto 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 -lsomethingat 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:

我有同样的问题。为了解决这个问题,需要做两件事:

  1. use the RTLD_GLOBALas other users said
  2. You need to load every library that is used by your library. So if ODBCGeneralQueryis defined in lets say libIDCodbc, you need first run this line:
  1. 使用RTLD_GLOBAL其他用户所说的
  2. 您需要加载您的库使用的每个库。因此,如果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_LAZYdue to an undefined symbol that was not linked because it was not being used. Since there is no ctypes.RTLD_LAZYin 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.hwhich is probably not standard. Hat tip to this 2006 threadon the ctypes mailing list.

我通过检查/usr/include/bits/dlfcn.h可能不标准的方式发现了这种模式。对 ctypes 邮件列表上的这个 2006主题的帽子提示。

回答by Rookie

Based on Walter Nissen's answerabove, you can modify the code to be:

根据上面 Walter Nissen 的回答,您可以将代码修改为:

import os
ctypes.CDLL(libidcwf_path, mode=os.RTLD_LAZY)