将对象引用列表传递给CFFI函数

时间:2018-03-14 19:16:55

标签: python c list pointers python-cffi

我正在编写一个项目,我需要处理许多树状数据元素,以克服一些性能问题,我想调用已经用C签名的给定处理函数,签名为Task和树节点定义为:

public class HandlerClass : DelegatingHandler { 
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { 

        var data = await request.Content.ReadAsStringAsync();

        // Log request in database

        var response = await base.SendAsync(request, cancellationToken);

        // Response Processing 

        return response;
    } 
}

因此,树节点可以具有任意数量的子节点。类似地,我的Python项目中的树节点定义为:

int process(Node* root)

要调用C函数,我想使用CFFI。我遇到的问题是我需要将我的Python树数据结构转换为匹配的C表示。可以通过以下方式创建可以传递给CFFI函数的节点表示:

typedef struct Node {
    int value;
    struct Node ** children;
    int num_children;
} Node;

但我找不到将子列表引用转换为class Node(): def __init__(self,value): self.value = value self.children = list() def add_child(self,child): self.children.append(child) 的方法。

1 个答案:

答案 0 :(得分:0)

C中的类型struct node **几乎等同于struct node *[],它代表“节点指针数组”。所以你想要array = ffi.new("struct node *[]", x)。如果它是一个整数,这将分配一个长度为x的数组;或者,您可以直接在x中输入cffi指针列表,例如array = ffi.new("struct node *[]", [child.as_cffi_pointer() for child in self.children])

请注意,只要需要,所有使用ffi.new()创建的cffi对象都必须手动保持活动状态。只是将C指针存储在某处不会使Python中的cffi对象保持活跃状态​​。如果你忘记保持Python端cffi对象,那么C指针将快速指向释放内存。这涉及ffi.new("struct node *")ffi.new("struct node *[]", x)