python ctype 递归结构
题
我用 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 正确理解它?
解决方案
您几乎可以肯定想声明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))]
其他提示
之所以
EthercatDatagram._fields_.append(("next_command", EthercatDatagram))
不起作用的是创建描述符对象的机制(请参阅 PyCStructType_setattro
函数)用于访问 next_command
属性被激活 仅在分配时 到 _fields_
类的属性。仅仅将新字段附加到列表中就完全不会被注意到。
为了避免这个陷阱,请始终使用元组(而不是列表)作为 _fields_
属性:这将清楚地表明您必须为该属性分配一个新值,而不是就地修改它。
您必须访问_fields_
您创建后静态的。
class EthercatDatagram(Structure)
_fields_ = [...]
EthercatDatagram._fields_.append(("next_command", EthercatDatagram))
不隶属于 StackOverflow