【问题标题】:Python ctype-bitfields: get bitfield locationPython ctypes-bitfields:获取位域位置
【发布时间】:2014-04-17 10:54:44
【问题描述】:

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

提前感谢您的每一个回复!

【问题讨论】:

    标签: python ctypes bit-fields


    【解决方案1】:

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

    由于你的bit-field存储单元都是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
    

    【讨论】:

    • 谢谢,这很有帮助!但是在我的机器上(我在 Window 机器上运行 Python 2.7.2)我不得不用“, _”更改“*”,以免收到投诉。但仍然很好的答案。
    • @eryksun:感谢您的精彩回答!你能告诉我这个关于位域大小和偏移量的东西是否可以在文档中找到?我在那里找不到它...
    • @maggie,文档简要提到了字段描述符类型,但没有记录属性。那就只剩下源了,比如PyCField_repr
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    • 1970-01-01
    • 2015-11-06
    相关资源
    最近更新 更多