首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python使用CDLL加载c lib时,在python路径中看不到库

python使用CDLL加载c lib时,在python路径中看不到库
EN

Stack Overflow用户
提问于 2012-02-05 02:46:48
回答 5查看 33.6K关注 0票数 9

我正在尝试使用一些开源的学术代码(项目主页是here)。它是一个很大的C++代码库,带有一个(非常)薄的python包装器,它使用CDLL加载C++并调用一些C函数,这些C函数允许对代码进行原始python脚本编写。

但是,最初的导入代码会崩溃,因为它在站点包中找不到旁边的.so文件:

在已安装的文件中:

代码语言:javascript
复制
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"

在脚本或解释器中:

代码语言:javascript
复制
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

Other回答might seem to have this covered,但只有在实际调用的脚本(或运行解释器的提示符的工作目录)中调用CDLL()时才有效-即,如果“相对路径”位于用户空间,而不是python库空间。

我们如何可靠地安装并导入我们自己构建的C/C++库?除了污染系统库位置,如/usr/lib,这不是非常pythonic,我看不到一个简单的解决方案。

(编辑:更正了函数名,不清楚的重构无济于事!对不起!)

EN

回答 5

Stack Overflow用户

发布于 2017-07-03 03:24:15

在linux上,我所做的就是把这个问题放在操作系统模块的绝对路径中,并且它起作用了。

代码语言:javascript
复制
from ctypes import *
import os

xss = cdll.LoadLibrary(os.path.abspath("libxss.so.1"))
print xss.xss_test_1()

这也是python 2.7。

票数 7
EN

Stack Overflow用户

发布于 2012-02-06 20:15:58

在strace -eopen下运行,您将看到如下所示:

代码语言:javascript
复制
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)

它显示了python ctype查找您的库的所有位置。到目前为止,我还找不到一个运行时环境变量tweak来在我的系统上添加搜索位置,也许你必须使用绝对路径。

票数 2
EN

Stack Overflow用户

发布于 2013-05-07 16:52:58

您可以在执行导入的包中使用__file__变量。只需使用os.path的各种功能从__file__中提取完整的绝对目录路径,然后将其连接到库文件名中。类似于:

代码语言:javascript
复制
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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9143440

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档