11

我已经为 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 正确理解它?

4

3 回答 3

16

您几乎肯定希望将 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))]
于 2009-08-04T16:12:55.377 回答
1

之所以

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

不起作用的是,创建PyCStructType_setattro用于访问属性的描述符对象(参见函数的源代码)的机制仅在分配给类的属性时才next_command被激活。仅仅将新字段附加到列表中就完全不会被注意到。_fields_

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

于 2013-07-24T12:11:36.527 回答
-2

_fields_创建它后,您必须静态访问它。

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

EthercatDatagram._fields_.append(("next_command", EthercatDatagram))
于 2009-08-04T15:33:59.910 回答