我用 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))
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top