在Python cffi中的库之间传递对象

德拉琴

如果使用创建新结构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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

是否可以在进程之间传递Python Future对象?

Python中的模块和库之间有什么区别?

在Python中,传递和返回之间有什么区别

Python NotImplementedError:无法在进程之间传递池对象

如何使用Python CFFI正确包装C库

通过Python中的套接字在两个进程之间传递共享内存对象

在Luigi中的Task之间传递Python对象?

使用CFFI从Python传递指向C函数的指针的最佳方法

在python中的进程之间共享对象

Segfault通过Boost Python在C ++对象之间传递共享指针

python对象之间的通信?

如何在Python中的方法之间传递变量?

Python OOP:在类之间传递值。对象和实例

在Python中的函数之间传递变量,然后返回菜单

对象之间的对象python

从AudioLazy库中的python中的zfilter对象中提取数值

在Windows上安装python库cffi

如何在python中的文件之间传递全局变量

python cffi库对象自省导致__dict__对象更改

在python中的json中传递的模拟文件对象

将对象方法传递给python中的外部函数

Python:对象中缺少“self”(不会自动传递)

将对象引用传递给 Python 中的多个类

Python中库、模块、包、对象的区别

将连接对象从进程传递到python中的主进程

在 Python 中动态传递对象属性作为方法的参数

将列表传递给 Robot Framework 中的 python 库

在gem5中Python和C++之间如何传递System对象的clk_domain等属性?

使用多个条件从 Python 中的数组对象传递值