Битовые значения полей структуры
Есть структура, объявление на С которой выглядит так:
struct Strip {
ULONG InJob: 1
ULONG Initializing : 1
ULONG UsingPool : 1
ULONG UsingPages : 1
ULONG FormFactor : 1
ULONG Reserved: 27
}
Как подобные структуры объявляются в Python? Как объявляются обычные структуры, без побитового значения полей, я знаю, например:
class Foo(Structure):
_fields_ = [('a', c_ulong), ('b', c_long)]
А вот как с битовыми значениями - не имею понятия.
Ответы (1 шт):
У ctypes.Structure есть битовые поля.
Для структуры
struct Strip {
unsigned long InJob: 1;
unsigned long Initializing : 1;
unsigned long UsingPool : 1;
unsigned long UsingPages : 1;
unsigned long FormFactor : 1;
unsigned long Reserved: 27;
}
эквивалентом будет
class Strip(ctypes.Structure):
_fields_ = [
("InJob", ctypes.c_ulong, 1),
("Initializing", ctypes.c_ulong, 1),
("UsingPool", ctypes.c_ulong, 1),
("UsingPages", ctypes.c_ulong, 1),
("FormFactor", ctypes.c_ulong, 1),
("Reserved", ctypes.c_ulong, 27),
]
Вот только битовые поля очень нестабильно работают в python: они не кросс-платформенные.
Существует встроенный модуль struct, он очень прост и функционален. Но, к сожалению, не умеет работать с отдельными битам, а только лишь с октетами.
Как альтернативу я использовал простые битовые маски:
class Strip:
def __init__(self, inputStream):
raw = struct.unpack("L", inputStream.read(4))
self.InJob = (raw & 0b0000000000000001) >> 0
self.Initializing = (raw & 0b0000000000000010) >> 1
self.UsingPool = (raw & 0b0000000000000100) >> 2
self.UsingPages = (raw & 0b0000000000001000) >> 3
self.FormFactor = (raw & 0b0000000000010000) >> 4
self.Reserved = (raw & 0b1111111111100000) >> 5
Вот тут можно посмотреть как я использовал этот подход.
P.S. только будьте осторожны с порядком байтов.