如何在ctypes中设置一个带有指针的结构?

时间:2015-05-24 13:05:56

标签: python ctypes

我有一个结构的以下C声明:

struct vnode {
   char firstchar;
   uint8_t wordlength;

   bool is_red;

   struct vnode *left;
   struct vnode *right;
   struct textelem *texts;
};

非常典型的树有一些有效载荷。我试图将其重写为以下ctypes声明:

class VNODE(Structure):
    _fields_ = [("firstchar", c_char),
                ("wordlength", c_ubyte),
                ("is_red", c_bool),
                ("left", POINTER(VNODE)),
                ("right", POINTER(VNODE)),
                ("textelem", POINTER(TEXTELEM))]

遗憾的是,这不起作用,因为当时python编译器还不知道类型VNODE

所以我把它改写成下面的课程:

class VNODE(Structure):
    def __init__(self):
        self._fields_ = [("firstchar", c_char),
                ("wordlength", c_ubyte),
                ("is_red", c_bool),
                ("left", POINTER(VNODE)),
                ("right", POINTER(VNODE)),
                ("textelem", POINTER(TEXTELEM))]

这不起作用,因为现在ctypes无法推断出正确的构造函数(我已经用一个参数编写了它)并且无法推断出正确的getter。所以我得到以下两个错误之一

TypeError: __init__() takes 1 positional argument but 7 were given
AttributeError: 'LP_VNODE' object has no attribute 'firstchar

最后,我提出了以下工作解决方案,但由于现在指针类型未编码,我不确定它是否真的是正确的方法:

class VNODE(Structure):
    _fields_ = [("firstchar", c_char),         
                ("wordlength", c_ubyte),        
                ("is_red", c_bool),     
                ("left", c_void_p),
                ("right", c_void_p),
                ("textelem", POINTER(TEXTELEM))]

1 个答案:

答案 0 :(得分:7)

您可以模拟C风格的 decleration ,然后是定义。见ctypes docs on incomplete types

>>> class VNODE(Structure):  # incomplete type / forward declaration
...     pass
... 
>>> VNODE._fields_ = [("firstchar", c_char),
...                   ("wordlength", c_ubyte),
...                   ("is_red", c_bool),
...                   ("left", POINTER(VNODE)),
...                   ("right", POINTER(VNODE))]