Python ctypes 位域

2024-09-27 23:19:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要一个与ctypes结构兼容的位域定义,这样我就可以用它作为指向一组硬件寄存器的内存映射集的指针

class RegFile(Structure):
    _fields_ = [
        ('ticks', c_uint32),
        ('id', id_bitfield),
    ]

理想的情况下,它们应该是非常像Python的东西,并且表现得像口述一样。我已经设法解决了大部分棘手的细节,现在我有一个工厂函数,它使位字段类类似于生成namedtuples。这里有一个例子,它撕开了一个标准浮点的字段。在

^{pr2}$

这很正常,但并不是一种特别的python感觉语法。最好的答案是

class IEEE754(Register):
    """Individual bitfields of a standard IEEE-754 floating point number."""
    _fields_ = ieee754_fields
    _basetype_ = c_float

但我没能让注册类成为一个东西。似乎Register应该从Union继承并应用一些元类魔术,但这样元类与Union lie冲突。有什么想法吗?还是我应该坚持我现有的?在


Tags: 内存registeridfields硬件定义ctypes结构
1条回答
网友
1楼 · 发布于 2024-09-27 23:19:35

您可以通过创建如下扩展type(ctypes.Union)的Register元类来实现所描述的内容:

class Register(type(ctypes.Union)):
    def __new__(mcs, name, bases, dict):
        #make the bitfield class
        class regBitfield(ctypes.LittleEndianStructure):
            _fields_ = dict['_fields_']
        #set up the Union
        class regUnion(ctypes.Union):
            _fields_ = [('base', dict['_basetype_']), ('_b', regBitfield)]
            _anonymous_ = ('_b', )
            __iter__ = _register_iter
            keys = _register_keys
            items = _register_items
            update = _register_update
        #return a subclass of the temporary regUnion class
        return type(ctypes.Union).__new__(mcs, name, (regUnion,), dict)

class IEEE754: #for Python3 use class IEEE754(metaclass=Register):
    __metaclass__ = Register #omit this line Python3
    _fields_ = [('mantissa', ctypes.c_uint, 23),
                ('exponent', ctypes.c_uint, 8),
                ('sign', ctypes.c_uint, 1)
               ]
    _basetype_ = ctypes.c_float

这与您的make_register函数的工作方式几乎相同,但是使用了类系统的现有机制和扩展ctypes.Unionctypes.Structure的特殊规则。具体地说,ctypes.Union或{}的子类的任何子类都将扩展_fields_列表,而不是替换它。知道了这一点,我们可以在最终类扩展的Register元类的__new__中创建临时类。以上内容:

^{pr2}$

如果要创建的类型有多个基,Register.__new__方法可能会中断。在

相关问题 更多 >

    热门问题