python ctype recursive structures

余生长醉 提交于 2019-12-12 04:54:50

问题


I've developped a DLL for a driver in C. I wrote a test program in C++ and the DLL works fine.

Now I'd like to interract with this DLL using Python. I've successfully hidden most of the user defined C structures but there is one point where I have to use C structures. I'm rather new to python so I may get things wrong.

My approach is to redefine a few structures in python using ctype then pass the variable to my DLL. However in these class I have a custom linked list which contains recursive types as follow

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

This fails, because inside EthercatDatagram, EthercatDatagram is not already defined so the parser returns an error.

How should I represent this linked list in python so that my DLL understands it correctly?


回答1:


You almost certainly want to declare next_command as a pointer. Having a structure that contains itself isn't possible (in any language).

I think this is what you want:

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))]



回答2:


The reason why

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

does not work is that the machinery that creates the descriptor objects (see the source of the PyCStructType_setattro function) for accessing the next_command attribute is activated only upon assignment to the _fields_ attribute of the class. Merely appending the new field to the list goes completely unnoticed.

To avoid this pitfall, use always a tuple (and not a list) as the value of the _fields_ attribute: that will make it clear that you have to assign a new value to the attribute and not modify it in place.




回答3:


You'll have to access _fields_ statically after you've created it.

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

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


来源:https://stackoverflow.com/questions/28879604/can-python-ctypes-structure-contain-itself

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!