是否可以创建间接递归的ctypes.Structure类型?

时间:2016-11-08 12:09:51

标签: python ctypes

这与#1228158#28879604不同。它很相似,但有一点扭曲。

创建一个引用其自身类型的递归类型是微不足道的:

A = type('A', (ctypes.Structure,), {})
A._fields_ = [('another_a', ctypes.POINTER(A))]

或者,如果您愿意:

class A(ctypes.Structure):
    pass
A._fields_ = [('another_a', ctypes.POINTER(A))]

同样的事情。如果他们不是一回事,那就教育我吧!

但我正在尝试将C structtypedef机器翻译成ctypes.Structure s。我希望Python端的名称和关系能够反映C方面的名称和关系。如果函数返回的uint32 typedefconsumer_id,我希望Python端的对象具有更具描述性的名称。现在,这是一种经常发生的事情:

typedef dummy_type official_type;
typedef struct dummy_struct {
    official_type *another_struct;
} dummy_type;

无论我如何扭曲和扭转这一点,我都无法在Python中实现这种关系。中间名称​​可能在任何地方都没有使用,所以目前我们正在考虑检测这种情况,只是让official_type ctypes.Structure引用自己。也许让dummy_typestruct dummy_struct类型引用自己。在二进制级别,在C方面,它们都是等价的。

但我真正想做的是:

Struct_dummy_struct = type('struct_dummy_struct', (ctypes.Structure,), {})
Dummy_type = type('dummy_type', (Struct_dummy_struct,), {})
Official_type = type('official_type', (Dummy_type,), {})
Struct_dummy_struct._fields_ = [('another_struct', ctypes.POINTER(Official_type))]

当然,这是不可能的:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: _fields_ is final

我认为我试图做的事情在理论上是不可能的,考虑到ctypes的工作方式,但是如果有人能告诉我那里的方式,我会很高兴的!

1 个答案:

答案 0 :(得分:0)

你在python中不需要相同的结构:

class official_type(ctypes.Structure):
    pass
official_type._fields_ = [("another_struct", ctypes.POINTER(official_type))]
first_instance = official_type()
second_instance = official_type()
first_instance.another_struct = ctypes.pointer(second_instance)
print first_instance.another_struct

<__main__.LP_official_type object at ...>

Ctypes有一个时髦的结构化完成过程,如果你深入研究单元测试,你会发现类似的东西:

  

结构/联盟课程必须完成&#39;迟早,当其中一件事发生时:

     
      
  1. _fields_已设置。
  2.   
  3. 创建了一个实例。
  4.   
  5. 该类型用作另一个Structure / Union的字段。
  6.   
  7. 类型是子类
  8.         

    完成后,不再允许分配字段。

也许使用类型的类定义会混淆过程。