我在C中有以下内容:
typedef struct {
short Whole;
unsigned short Frac;
} FirstStruct, FAR *pFirstStruct;
typedef struct {
char FirstArr[3];
FirstStruct SecondArr[3][3]
} SecStruct, FAR * pSecStruct;
我想在Python中做一些类似的事情。找到this answer解释如何使用ctypes
来实现这个目的,但是我在使用SecondArr[3][3]
时遇到了问题。下面是Python中的代码:
class FirstStruct(ctypes.Structure):
_pack_ = 2
_fields = [("Whole", ctypes.c_short),
("Fract", ctypes.c_ushort)]
class SecStruct(ctypes.Structure):
class _A(ctypes.Array):
_type_ = ctypes.c_char
_length_ = 3
class _B(ctypes.Array):
_type_ = FirstStruct
_length_ = 3
class _C(ctypes.Array):
_type_ = _B
_length_ = 3
_pack_ = 2
_fields = [("FirstArr", _A),
("SecondArr", _C)]
这样做,Pylance抱怨"_B" is not defined
,我不完全确定它是否有效,也不确定以这种方式混合两个子类来创建一个新的C结构是否安全。
即使Pylance抱怨,这是正确的做法吗?或者有没有其他方法来转换提到的结构?
2条答案
按热度按时间83qze16e1#
根据[Python. Docs]:ctypes-数组(强调是我的):
数组是序列,包含固定数量的相同类型的示例。
创建数组类型的推荐方法是将数据类型与正整数相乘:
此外(不确定是否是 * 错字 ),对于结构,保存成员数据的属性名是**fields(也以 * UnderScore结尾,而不是*_fields***(如您的情况))。
我不打算讨论代码中的问题(* NameError * s),因为它们是由误解产生的,(因此)是一个完全不同的问题。
下面是一个小例子,注意我是逐渐声明数组类型的(为了可读性),但是也可以动态声明(只在需要的地方)。
然后可以像在 * C * 中那样操作示例。
可能还值得一读:
5vf7fwbs2#
下面显示了用一个类型乘以一个整数来创建一个数组,但是注意C是以行为主的顺序存储数组的。要创建具有正确内存布局的数组,首先乘以列的大小来创建一个单行数组,然后乘以行的大小来完成数组。在你的例子[3][3]中,这并不重要,但是如果大小不同的话,这就很重要了,就像我特意展示的那样。
每个struct还包含一个
__repr__
函数,用于定义结构如何显示自身,并从连续编号的字节缓冲区创建一个示例,以说明正确的little-endian布局:输出: