Python ctypes 位域 : get bitfield location

标签 python ctypes bit-fields

我已经创建了一个带有相应联合体的 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”索引,但我找不到任何东西 有没有一种简单的方法可以做到这一点?

预先感谢您的每一个回复!

最佳答案

Structure 中的每个字段描述符都有一个offset 属性,用于定义其存储单元的字节偏移量。它还有一个 size 属性,其含义取决于它是否是一个位字段。如果是位字段,size 的低位字包含字段的存储单元位偏移量,高位字包含字段中的位数。否则 size 是字段的字节大小。

由于你的位域存储单元都是c_short,你可以简单地将一个字段的字节offset除以sizeof(c_short)来计算asInt 中的相应项目。例如,Flags_bits.bitField6.offset//2 == 0Flags_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

关于Python ctypes 位域 : get bitfield location,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23131237/

相关文章:

python - 如何通过Scrapy收集jpeg

python - 如何在不最大化的情况下制作一个占据全屏的窗口?

python - 将 numpy.array 传递给 ctypes 但得到错误结果的问题

python - Py_Initialize 运行需要哪些文件?

c - 在 C90 中将位字段和其他数据类型作为单个结构中的字段是不好的做法吗?

python - pygame:获取音乐的当前时间

javascript - 如何制作调查机器人?

python - 如何将字节从 ctypes 结构复制到从 create_string_buffer 创建的缓冲区

无符号位字段值与有符号值的比较

c# - 在 C# 中,如何轻松地将枚举标志从一种类型映射到另一种类型?