python ctype递归结构 我在C中为驱动程序开发了一个DLL。我用C++编写了一个测试程序,DLL工作得很好。

python ctype递归结构 我在C中为驱动程序开发了一个DLL。我用C++编写了一个测试程序,DLL工作得很好。,python,dll,recursion,structure,ctypes,Python,Dll,Recursion,Structure,Ctypes,现在我想使用Python与这个DLL交互。我已经成功地隐藏了大多数用户定义的C结构,但是有一点我必须使用C结构。我对python比较陌生,所以可能会出错 我的方法是使用ctype在python中重新定义一些结构,然后将变量传递给我的DLL。然而,在这些类中,我有一个自定义链表,其中包含如下递归类型 class EthercatDatagram(Structure): _fields_ = [("header", EthercatDatagramHeader),

现在我想使用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正确理解它?

创建链表后,您必须静态地访问它

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

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

您几乎肯定希望将下一个_命令声明为指针。在任何语言中都不可能拥有包含自身的结构

我想这就是你想要的:

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))
不起作用的是,创建描述符对象的机制(用于访问下一个命令属性的函数源)仅在分配给类的_fields_u属性时激活。 仅仅将新字段添加到列表中完全不会引起注意


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

这不起作用。它编译并运行,但尝试实际使用该类的实例时会出现错误:AttributeError:“EthercatDatagram”对象没有属性“next_command”正确答案如下,如用户9876所示,您必须首先使用“pass”声明该类,然后在第二次调用中声明字段。可以将其视为转发声明。这在任何语言中都是不可能的——对于c/c++/java风格的结构或类来说也是如此,但在具有代数数据类型的语言中,它不仅是可能的,而且非常常见。e、 g.数据列表a=Cons在ML系列语言ocaml/haskell/SML/etc中的列表a | Nil。在这些语言中,它仍然作为指针实现;该语言只是将指针的细节抽象出来。结构是一个连续的内存序列,其大小由其组件大小之和决定,因此要包含自身的副本,它必须比自身大,这是不可能的。