使用 cffi 加载 .so 库
loading .so library with cffi
我想使用 CFFI 在 Python 中访问一些 C 库。构建库后,我得到了 2 个文件:$HOME/libcint/include/cint.h
和 $HOME/libcint/lib/libcint.so
.
现在我尝试了 CFFI API 模式:
from cffi import FFI
libcint_dir = os.path.expanduser('~/libcint')
ffibuilder = FFI()
ffibuilder.set_source('_libcint',
r'#include <include/cint.h>',
include_dirs = [libcint_dir],
libraries = ['libcint'],
library_dirs = [os.path.join(libcint_dir, 'lib')],
)
但是找不到 libcint.so
文件:
/usr/bin/ld: cannot find -llibcint
libcint_dir
中的路径是正确的,因为我没有收到任何关于找不到头文件的错误信息。我还设法使用 ctypes
模块成功连接了库,因此 libcint.so
本身应该没问题。
我做错了什么?
如果我做对了,那么这里需要 3 个步骤。 (如果我在这里混淆了什么,请纠正我。)
- 编译 libcint 产生
libcint.so
- 使用 CFFI
构建 Python 包装器
- 将步骤 2 中构建的模块导入到实际的 Python 程序中
我这里的问题是关于第二步的。
您可能被编译时间与库的 运行 时间位置的问题困扰。您提供给库的路径仅在 GCC 编译时使用。在 运行 时,它会查找名称正确的库,但仅使用系统配置的默认路径。所以你需要告诉系统在哪里可以找到那个库。您可以执行以下操作之一:
将库移动到标准位置,如 /usr/local/lib
;
运行 加上环境变量 LD_LIBRARY_PATH=/path/to/library
;
如果你想在编译模块中硬编码路径,你可以在调用set_source()时使用extra_link_args=['-Wl,-rpath=' + path]
。
这都是假设 Linux。在不同的平台上,这三个选项可能也都可用,但细节有所不同...
您说的是 libraries = ['libcint']
,这意味着编译器将查找名为 liblibcint.so
的文件。因此你应该写的是 libraries = ['cint']
.
我想使用 CFFI 在 Python 中访问一些 C 库。构建库后,我得到了 2 个文件:$HOME/libcint/include/cint.h
和 $HOME/libcint/lib/libcint.so
.
现在我尝试了 CFFI API 模式:
from cffi import FFI
libcint_dir = os.path.expanduser('~/libcint')
ffibuilder = FFI()
ffibuilder.set_source('_libcint',
r'#include <include/cint.h>',
include_dirs = [libcint_dir],
libraries = ['libcint'],
library_dirs = [os.path.join(libcint_dir, 'lib')],
)
但是找不到 libcint.so
文件:
/usr/bin/ld: cannot find -llibcint
libcint_dir
中的路径是正确的,因为我没有收到任何关于找不到头文件的错误信息。我还设法使用 ctypes
模块成功连接了库,因此 libcint.so
本身应该没问题。
我做错了什么?
如果我做对了,那么这里需要 3 个步骤。 (如果我在这里混淆了什么,请纠正我。)
- 编译 libcint 产生
libcint.so
- 使用 CFFI 构建 Python 包装器
- 将步骤 2 中构建的模块导入到实际的 Python 程序中
我这里的问题是关于第二步的。
您可能被编译时间与库的 运行 时间位置的问题困扰。您提供给库的路径仅在 GCC 编译时使用。在 运行 时,它会查找名称正确的库,但仅使用系统配置的默认路径。所以你需要告诉系统在哪里可以找到那个库。您可以执行以下操作之一:
将库移动到标准位置,如
/usr/local/lib
;运行 加上环境变量
LD_LIBRARY_PATH=/path/to/library
;如果你想在编译模块中硬编码路径,你可以在调用set_source()时使用
extra_link_args=['-Wl,-rpath=' + path]
。
这都是假设 Linux。在不同的平台上,这三个选项可能也都可用,但细节有所不同...
您说的是 libraries = ['libcint']
,这意味着编译器将查找名为 liblibcint.so
的文件。因此你应该写的是 libraries = ['cint']
.