Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python cffi中的库之间传递对象_Python_Python Cffi - Fatal编程技术网

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

在Python cffi中的库之间传递对象,python,python-cffi,Python,Python Cffi,如果我使用cffi.FFI.new创建一个新结构,我如何将它从具有相同结构定义的不同FFI传递给函数 我有一个基本的C结构,我通过cffi包在Python中使用它,我想在运行时将它传递给cffi生成和编译的各种函数。但是,我不知道如何使生成的函数共享相同的结构定义,以便在它们之间传递对象。当使用一个FFI构建对象并将其从另一个FFI传递给函数时,cffi不喜欢它 下面是一个简化的可运行结构定义示例,并使用Python创建实例: from cffi import FFI common_heade

如果我使用
cffi.FFI.new
创建一个新结构,我如何将它从具有相同结构定义的不同
FFI
传递给函数

我有一个基本的C结构,我通过cffi包在Python中使用它,我想在运行时将它传递给cffi生成和编译的各种函数。但是,我不知道如何使生成的函数共享相同的结构定义,以便在它们之间传递对象。当使用一个
FFI
构建对象并将其从另一个
FFI
传递给函数时,cffi不喜欢它

下面是一个简化的可运行结构定义示例,并使用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)
这个错误很清楚它为什么不高兴。它不喜欢我使用
ffibuilder
构造
my_对象
,并将其传递给另一个
FFI
中定义的函数,该函数有自己的
my_结构
类型定义


如何编译生成的函数以与中心FFI共享结构定义?

您可以使用
FFI.include
将一个
FFI
实例的源代码和定义包含在另一个实例中。使用包含的
FFI
构造的对象可以传递到包含它的
FFI
中的函数

请注意,包含的定义不能在以后的
FFI
中重复。此外,只有对
set\u source
进行了调用,才能包含
FFI
。这是真实的,即使你想要的只是标题;在这种情况下,只需将源设置为空字符串

下面是在主
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
# 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