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

Pass a list of object references to a CFFI function

我正在编写一个项目,我需要处理许多树状数据元素,为了克服一些性能问题,我想调用一个已经用 C 语言编写的给定处理函数,签名为 int process(Node* root) 和树节点定义为:

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

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

class Node():
    def __init__(self,value):
        self.value = value
        self.children = list()

    def add_child(self,child):
        self.children.append(child)

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

ffi_node = ffi.new("Node *")
ffi_node.value = some_value

但我找不到将对子项的列表引用转换为 struct Node** children

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

请注意,使用 ffi.new() 创建的所有 cffi 对象必须根据需要手动保持活动状态。仅将 C 指针存储在某处不会使 Python 中的 cffi 对象保持活动状态。如果您忘记使 Python-side cffi 对象保持活动状态,则 C 指针将快速指向已释放的内存。这涉及 ffi.new("struct node *")ffi.new("struct node *[]", x)