是否可以创建间接递归 ctypes.Structure 类型?
Is it at all possible to create indirectly recursive ctypes.Structure types?
这与 #1228158 or #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 struct
s 和 typedef
s 机器翻译成 ctypes.Structure
s。我希望 Python 端的名称和关系反映 C 端的名称和关系。如果一个函数返回一个 uint32
被 typedef
编辑为 consumer_id
,我希望 Python 一侧的对象具有更具描述性的名称。现在,这是一种经常发生的事情:
typedef dummy_type official_type;
typedef struct dummy_struct {
official_type *another_struct;
} dummy_type;
无论我如何曲折,我都无法实现Python中的这种关系。中间名称 可能 没有在任何地方使用,所以目前我们的想法是检测这种情况,只是让 official_type
成为 ctypes.Structure
引用本身。并且可能使 dummy_type
和 struct 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
的工作方式,我认为我尝试做的事情在理论上是不可能的,但如果有人能告诉我有办法,我会很高兴!
您不需要在 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 有一个时髦的结构完成过程,如果你深入研究单元测试,你会发现类似的东西:
Structure/Union classes must get 'finalized' sooner or later, when one of these things happen:
- _fields_ is set.
- An instance is created.
- The type is used as field of another Structure/Union.
- The type is subclassed
When they are finalized, assigning fields is no longer allowed.
也许您使用类型的 class 定义弄乱了过程。
这与 #1228158 or #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 struct
s 和 typedef
s 机器翻译成 ctypes.Structure
s。我希望 Python 端的名称和关系反映 C 端的名称和关系。如果一个函数返回一个 uint32
被 typedef
编辑为 consumer_id
,我希望 Python 一侧的对象具有更具描述性的名称。现在,这是一种经常发生的事情:
typedef dummy_type official_type;
typedef struct dummy_struct {
official_type *another_struct;
} dummy_type;
无论我如何曲折,我都无法实现Python中的这种关系。中间名称 可能 没有在任何地方使用,所以目前我们的想法是检测这种情况,只是让 official_type
成为 ctypes.Structure
引用本身。并且可能使 dummy_type
和 struct 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
的工作方式,我认为我尝试做的事情在理论上是不可能的,但如果有人能告诉我有办法,我会很高兴!
您不需要在 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 有一个时髦的结构完成过程,如果你深入研究单元测试,你会发现类似的东西:
Structure/Union classes must get 'finalized' sooner or later, when one of these things happen:
- _fields_ is set.
- An instance is created.
- The type is used as field of another Structure/Union.
- The type is subclassed
When they are finalized, assigning fields is no longer allowed.
也许您使用类型的 class 定义弄乱了过程。