python ctype递归结构

时间:2009-08-04 15:25:04

标签: python dll recursion structure ctypes

我在C中为驱动程序开发了一个DLL。我用C ++编写了一个测试程序,DLL工作正常。

现在我想使用Python来处理这个DLL。我已成功隐藏了大多数用户定义的C结构,但有一点我必须使用C结构。我对python很新,所以我可能会弄错。

我的方法是使用ctype在python中重新定义一些结构,然后将变量传递给我的DLL。但是在这些类中,我有一个自定义链表,其中包含递归类型,如下所示

class EthercatDatagram(Structure):
    _fields_ = [("header", EthercatDatagramHeader),
                ("packet_data_length", c_int),
                ("packet_data", c_char_p),
                ("work_count", c_ushort),
                ("next_command", EthercatDatagram)]

这失败了,因为在EthercatDatagram中,尚未定义EthercatDatagram,因此解析器返回错误。

我应该如何在python中表示这个链表,以便我的DLL能够正确理解它?

3 个答案:

答案 0 :(得分:15)

您几乎肯定希望将next_command声明为指针。拥有一个包含自身的结构是不可能的(用任何语言)。

我认为这就是你想要的:

class EthercatDatagram(Structure):
    pass
EthercatDatagram._fields_ = [
    ("header", EthercatDatagramHeader),
    ("packet_data_length", c_int),
    ("packet_data", c_char_p),
    ("work_count", c_ushort),
    ("next_command", POINTER(EthercatDatagram))]

答案 1 :(得分:0)

原因

EthercatDatagram._fields_.append(("next_command", EthercatDatagram))

不起作用是创建描述符对象(参见PyCStructType_setattro函数的来源)以访问next_command属性的机制仅在分配时激活该类的_fields_属性。 仅将新字段添加到列表中就完全没有被注意到了。

为了避免这个陷阱,请始终使用元组(而不是列表)作为_fields_属性的值:这将清楚地表明您必须为属性分配新值而不是修改它到位。

答案 2 :(得分:-1)

您必须在创建后静态访问_fields_

class EthercatDatagram(Structure)
  _fields_ = [...]

EthercatDatagram._fields_.append(("next_command", EthercatDatagram))