10

我正在尝试让一些开源学术代码工作(项目主页在这里)。它是一个大型 C++ 代码库,带有一个(非常)薄的 Python 包装器,用于CDLL加载 C++ 并调用一些可用于允许代码的原始 Python 脚本编写的 C 函数。

但是,初始导入代码会崩溃,因为它在站点包中找不到位于其旁边的 .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

其他答案似乎已经涵盖了这一点,但这仅CDLL()在实际调用的脚本(或运行解释器的提示的工作目录)中调用时才有效 - 即如果“相对路径”在用户空间中,而不是python库空间。

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

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

4

5 回答 5

7

我在 linux 上,我为解决这个问题所做的只是将 os 模块的绝对路径放在了绝对路径中,它可以工作

from ctypes import *
import os

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

这也是python 2.7。

于 2017-07-02T19:24:15.063 回答
2

您可以使用__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.solibglob.glob

我不得不说我认为标准库中不存在这样的函数很奇怪。对于ctypes.util.find_library这种用途(我认为这很普遍),它不够灵活(或彻底)。即使只是一个搜索PYTHONPATH文件的函数也会非常有用(虽然不难写)。

话又说回来,如果您只是将正确的目录添加到 中LD_LIBRARY_PATH,您应该能够加载它

于 2013-05-07T08:52:58.303 回答
2

在 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)

它向您显示了 python ctypes 查找您的库的所有位置。到目前为止,我无法找到运行时环境变量调整以使其在我的系统上添加搜索位置,也许您必须使用绝对路径。

于 2012-02-06T12:15:57.763 回答
2

您必须指定绝对路径。尝试以下操作:

import os
from ctypes import *

try:
  slib = os.getcwd() + '/' +'_lammps.so'
  hlibc = CDLL(slib)
  hilbc.FunctionName()
except:
  try:
    slib = os.getcwd() + '/' +'_lammps_serial.so'
    hlibc = CDLL(slib)
  except:
    raise OSError,"Could not load LAMMPS dynamic library"
于 2018-06-25T12:29:41.837 回答
1

在通过 ctypes 导入相关库之前,将相关文件夹放入 PATH 变量中。

例如,如果库(dll,...)与 .py 文件位于同一文件夹中:

import os
os.environ["PATH"] += os.pathsep + os.path.dirname(os.path.abspath(__file__))

这不会向您的系统 PATH 写入任何内容。它只会为此实例设置它。

于 2020-01-15T17:25:27.197 回答