Python ctype位域:获取位域位置
我创建了一个ctype位域结构,并且有一个对应的联合体,可以通过单个位域和整数值来访问它。通过一个包含字段名称的变量,我能够设置单个字段,但现在我想知道这个特定字段属于哪个字节。
这是我的代码示例:
import ctypes
c_short = ctypes.c_uint16
class Flags_bits(ctypes.LittleEndianStructure):
_fields_ = [
("bitField1", c_short, 1),
("bitField2", c_short, 4),
("bitField3", c_short, 6),
("bitField4", c_short, 1),
("bitField5", c_short, 2),
("bitField6", c_short, 2),
("bitField7", c_short, 6),
("bitField8", c_short, 4),
("bitField9", c_short, 4),
("bitField10", c_short, 1),
("bitField11", c_short, 1)]
class Flags(ctypes.Union):
_fields_ = [("b", Flags_bits),
("asInt", c_short*6)]
def setFlag (flagName, value):
flags = Flags()
setattr(flags.b, flagName, value)
print getattr(flags.b, flagName)
现在我想知道我的标志属于哪个整数(也就是说,属于flags.asInt[i]中的哪个),我在寻找一种类似“get_location”的属性来获取标志在结构中的位置,从而找出整数的'i'索引,但我找不到任何相关的内容。
有没有简单的方法可以做到这一点?
提前感谢每一个回复!
1 个回答
9
在一个Structure
中,每个字段描述符都有一个offset
属性,这个属性定义了它在存储单元中的字节偏移量。它还有一个size
属性,这个属性的含义取决于它是否是一个位字段。如果是位字段,size
的低字部分包含字段的存储单元的位偏移量,而高字部分则包含字段中的位数。否则,size
就是字段的字节大小。
因为你的位字段存储单元都是c_short
类型,所以你可以简单地用字段的字节offset
除以sizeof(c_short)
来计算在asInt
中的对应项。例如,Flags_bits.bitField6.offset // 2 == 0
,而Flags_bits.bitField7.offset // 2 == 1
。
你还可以计算每个字段的位范围:
import ctypes
c_short = ctypes.c_cshort
class Flags_bits(ctypes.LittleEndianStructure):
_fields_ = [("bitField1", c_short, 1),
("bitField2", c_short, 4),
("bitField3", c_short, 6),
("bitField4", c_short, 1),
("bitField5", c_short, 2),
("bitField6", c_short, 2),
("bitField7", c_short, 6),
("bitField8", c_short, 4),
("bitField9", c_short, 4),
("bitField10", c_short, 1),
("bitField11", c_short, 1)]
for field_descr in Flags_bits._fields_:
name = field_descr[0]
field = getattr(Flags_bits, name)
bfield_bits = field.size >> 16
if bfield_bits:
start = 8 * field.offset + field.size & 0xFFFF
stop = start + bfield_bits
else:
start = 8 * field.offset
stop = start + 8 * field.size
print("{:>10s}: bits {:>2d}:{:>2d}".format(
name, start, stop))
输出:
bitField1: bits 0: 1
bitField2: bits 1: 5
bitField3: bits 5:11
bitField4: bits 11:12
bitField5: bits 12:14
bitField6: bits 14:16
bitField7: bits 16:22
bitField8: bits 22:26
bitField9: bits 26:30
bitField10: bits 30:31
bitField11: bits 31:32