如何在 Python 中实现 C 接口并使用 CFFI 传递对象
How to implement a C interface in Python and pass objects using CFFI
我想知道如何使用现有的 C 接口(头文件)并使用 CFFI 库在 Python 中实现这样的接口。
例如,我有以下头文件,interface.h
:
void* foo(void* value);
而且我想在Python中实现它。我认为下面的程序可以完成这项工作,但事实并非如此。它创建函数 foo
,但不保证实现遵循头文件中定义的结构。
import cffi
ffibuilder = cffi.FFI()
with open('interface.h') as f:
data = ''.join([line for line in f if not line.startswith('#')])
ffibuilder.embedding_api(data)
ffibuilder.set_source("_lib", r'''
#include "interface.h"
''')
ffibuilder.embedding_init_code("""
from _lib import ffi
#include "interface.h"
@ffi.def_extern()
def foo(param):
return __import__(param)
""")
ffibuilder.compile(verbose=True)
如何使用 CFFI 传递 Python 对象?
在上面的示例中,作为调用 foo
的结果,return 是一个 Python 对象。
然后在客户端,我有以下内容:
ffi = FFI()
# Load my lib file
lib = C.CDLL(dll)
h = lib.foo("math")
当我查看h的值时,它显示了一个数字类型的整数。但是,我期待收到一个对象。根据接口,foo
必须return一个指针void*
。我如何从中读取该对象?我做错了什么吗?
回答您的最后一个问题:您在此示例中使用的是 ctypes
,而不是 cffi
。这些是不同的项目。应该很明显,因为 ffi
对象来自 cffi
,但在以下行中未使用。而不是 lib = C.CDLL()
我猜 C
是 ctypes
的别名,你应该调用 lib = ffi.dlopen("...")
!
我发现问题是在从 ctypes 切换到 CFFI 以加载 DLL 时。第一个要求定义动态库中可用的方法。
因此,添加这个可以解决问题
ffi.cdef("""
void foo(void* value);
""")
我想知道如何使用现有的 C 接口(头文件)并使用 CFFI 库在 Python 中实现这样的接口。
例如,我有以下头文件,interface.h
:
void* foo(void* value);
而且我想在Python中实现它。我认为下面的程序可以完成这项工作,但事实并非如此。它创建函数 foo
,但不保证实现遵循头文件中定义的结构。
import cffi
ffibuilder = cffi.FFI()
with open('interface.h') as f:
data = ''.join([line for line in f if not line.startswith('#')])
ffibuilder.embedding_api(data)
ffibuilder.set_source("_lib", r'''
#include "interface.h"
''')
ffibuilder.embedding_init_code("""
from _lib import ffi
#include "interface.h"
@ffi.def_extern()
def foo(param):
return __import__(param)
""")
ffibuilder.compile(verbose=True)
如何使用 CFFI 传递 Python 对象?
在上面的示例中,作为调用 foo
的结果,return 是一个 Python 对象。
然后在客户端,我有以下内容:
ffi = FFI()
# Load my lib file
lib = C.CDLL(dll)
h = lib.foo("math")
当我查看h的值时,它显示了一个数字类型的整数。但是,我期待收到一个对象。根据接口,foo
必须return一个指针void*
。我如何从中读取该对象?我做错了什么吗?
回答您的最后一个问题:您在此示例中使用的是 ctypes
,而不是 cffi
。这些是不同的项目。应该很明显,因为 ffi
对象来自 cffi
,但在以下行中未使用。而不是 lib = C.CDLL()
我猜 C
是 ctypes
的别名,你应该调用 lib = ffi.dlopen("...")
!
我发现问题是在从 ctypes 切换到 CFFI 以加载 DLL 时。第一个要求定义动态库中可用的方法。 因此,添加这个可以解决问题
ffi.cdef("""
void foo(void* value);
""")