如果使用创建新结构cffi.FFI.new
,如何将其传递给FFI
结构定义相同的其他函数?
我有一个基本的C结构,正在通过cffi包在Python中使用,我想在运行时传递给cffi生成和编译的各种函数。但是,我不知道如何使生成的函数共享相同的结构定义,以便我可以在它们之间传递对象。当使用一个对象构建对象并将另一个对象FFI
传递给函数时,cffi不喜欢它FFI
。
这是结构定义和在Python中创建实例的简化可运行示例:
from cffi import FFI
common_header = """
typedef struct {
int32_t a;
double b;
} my_struct;
"""
# FFI for building objects
ffibuilder = FFI()
ffibuilder.cdef(common_header)
# Build an object in Python
my_object = ffibuilder.new('my_struct*')
my_object.a = 3
my_object.b = 2.0
我有一个外部库,该库生成函数的源代码,这些函数采用指向此结构实例的指针。我目前使用CFFI的API模式进行编译。这里重要的是,这些函数可以在构造对象之后生成,因此我不能简单地提前将所有函数收集在一起并将它们编译为一个库。
# Builder for functions generated at runtime
def build_library(header: str, source: str):
from tempfile import TemporaryDirectory
ffitemp = FFI()
ffitemp.cdef(common_header + header)
ffitemp.set_source('_temp', source)
with TemporaryDirectory() as temp_dir:
lib_path = ffitemp.compile(tmpdir=temp_dir)
lib = ffitemp.dlopen(lib_path)
return lib.func
# Use function
header = """
int func(my_struct *A);
"""
source = """
typedef struct {
int32_t a;
double b;
} my_struct;
int func(my_struct *A) {
return A -> a;
}
"""
func = build_library(header, source)
当我尝试将我的结构实例传递给函数时,出现一个错误,提示我传递的结构与该函数接受的结构类型不同。
# Use function
a = func(my_object)
print(a)
TypeError: initializer for ctype 'my_struct *' appears indeed to be
'my_struct *', the types are different (check that you are not e.g.
mixing up different ffi instances)
该错误很清楚为什么不满意。它不喜欢我my_object
使用ffibuilder
它构造并传递给在different中定义的函数FFI
,后者具有自己的my_struct
类型定义。
如何获得所生成函数的编译结果以与中央FFI共享结构定义?
您可以用来在另一个实例中FFI.include
包含一个FFI
实例的源和定义。使用include构造的对象FFI
可传递给包含该对象的函数FFI
。
请注意,包含的定义以后不能重复FFI
。另外,FFI
只有在set_source
已被调用的情况下,才能将其包括在内。即使您只需要标题也是如此。在这种情况下,只需将源设置为空字符串。
这是在主机上设置空源FFI
:
from cffi import FFI
common_header = """
typedef struct {
int32_t a;
double b;
} my_struct;
"""
# FFI for building objects
ffibuilder = FFI()
ffibuilder.cdef(common_header)
ffibuilder.set_source('_main', '') # <-- Set empty source
这包括FFI
叶子中的主体FFI
:
# Builder for functions generated at runtime
def build_library(header: str, source: str):
from tempfile import TemporaryDirectory
ffitemp = FFI()
ffitemp.include(ffibuilder) # <-- include main FFI
ffitemp.cdef(header)
ffitemp.set_source('_temp', source)
with TemporaryDirectory() as temp_dir:
lib_path = ffitemp.compile(tmpdir=temp_dir)
lib = ffitemp.dlopen(lib_path)
return lib.func
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句