我在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能够正确理解它?
答案 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))