python加载与CDLL c lib,没有看到python路径中的库
我试图让一些开源学术代码工作(项目主页是here)。它是一个很大的C++代码库,它有一个非常薄的python包装器,它使用CDLL
来加载C++并调用一些可用的C函数来允许代码的原始python脚本。python加载与CDLL c lib,没有看到python路径中的库
然而,最初的导入代码崩溃,因为它无法找到.so文件坐在旁边给它的站点包:
from ctypes import *
try:
self.lib = CDLL("_lammps.so")
except:
try:
self.lib = CDLL("_lammps_serial.so")
except:
raise OSError,"Could not load LAMMPS dynamic library"
,并在脚本:
在安装文件或解释:
from lammps import lammps
l = lammps()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lammps.py", line 42, in __init__
raise OSError,"Could not load LAMMPS dynamic library"
OSError: Could not load LAMMPS dynamic library
其他答案might seem to have this covered,但这只适用于如果CDLL()
实际上是调用脚本中调用(或工作目录在运行解释器的提示符处) - 即,如果'相对路径'在用户空间而不是python-library-space中。
我们如何可靠地安装导入我们自己构建的C/C++库?对污染系统库位置如/usr/lib
这不是很pythonic,我看不到一个简单的解决方案。
(编辑:更正函数名,重构不清楚无益的后悔!)下使用strace -eopen
运行,你会看到这样的事情:
open("tls/x86_64/_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("tls/_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("x86_64/_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
open("/lib/_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
它会显示所有的位置,其中蟒蛇ctypes寻找你的图书馆。 到目前为止,我无法找到一个运行时环境变量调整,使其在我的系统上添加搜索位置,也许你必须使用绝对路径。
谢谢,我会在我有一点时间。我在Mac OS X上,所以我不得不将你的strace建议移植到dtrace上(希望不要太糟糕)。 – tehwalrus 2012-02-07 15:06:53
您可以在执行导入的包中使用__file__
变量。只需使用os.path
的各种功能从__file__
中提取完整的绝对目录路径,然后将其加入到您的库文件名。喜欢的东西:
temp = os.path.abspath(__file__)
temp = os.path.realpath(temp)
temp = os.path.dirname(temp)
temp = os.path.join(temp, "_lammps.so")
lib = CDLL(path)
您也可能想尝试你的核心文件名的各种变化(即与.dll
或.dylib
代替.so
,并且有和没有一个lib
前缀,甚至有版本号追加)如果你想成为平台独立的,你的构建系统可能会产生这样的东西。然后,您可以尝试多个版本,或者使用glob.glob
来帮助您找到可接受的版本。
我不得不说我认为奇怪的是标准库中没有这样的函数。 ctypes.util.find_library
不足够灵活(或彻底),这种用途(我认为这是普遍的)。即使只是一个通过文件搜索PYTHONPATH
的功能将是非常有用的(虽然不难写)。
然后再次,似乎如果您只是将正确的目录添加到LD_LIBRARY_PATH
,您的should be able to load it。
林在Linux上,我所做的来解决这个问题置于从os模块的绝对路径,和它的作品
from ctypes import *
import os
xss = cdll.LoadLibrary(os.path.abspath("libxss.so.1"))
print xss.xss_test_1()
这是蟒蛇2.7为好。
更进一步:有问题的库有一个符号丢失,所以这段代码可能掩盖了一个不同的错误;人们不应该假设你知道系统异常是什么,并抛出你自己的!事实上,这个问题在进一步调查后仍然有效;系统*是第一次抛出正确的错误(我通过将.so复制到'/ usr/lib'并在交互式提示符下运行'CDLL()'来测试。) – tehwalrus 2012-02-05 10:35:09