Я не проверял это строго, но, похоже, он работает с неподписанными типами (редактировать: он также работает со знаковыми байтовыми / короткими типами).
Редактировать 2: Это действительно удар или промах. Это зависит от способа компиляции библиотеки битами в структуру, которая не стандартизирована. Например, в gcc 4.5.3 он работает до тех пор, пока я не использую атрибут для упаковки структуры, то есть __attribute__ ((__packed__))
(поэтому вместо 6 байтов он упаковывается в 4 байта, которые можно проверить с помощью __alignof__
и sizeof
). Я могу заставить его почти работать, добавив _pack_ = True
к определению структуры ctypes, но для fieldE это не получится. gcc отмечает: «Смещение упакованного битового поля« fieldE »изменилось в GCC 4.4».
import ctypes
class MyHeader(ctypes.Structure):
_fields_ = [
('fieldA', ctypes.c_ubyte, 3),
('fieldB', ctypes.c_ubyte, 2),
('fieldC', ctypes.c_ubyte, 3),
('fieldD', ctypes.c_ushort, 14),
('fieldE', ctypes.c_ubyte, 4),
]
lib = ctypes.cdll.LoadLibrary('C/bitfield.dll')
hdr = MyHeader()
lib.set_header(ctypes.byref(hdr))
for x in hdr._fields_:
print("%s: %d" % (x[0], getattr(hdr, x[0])))
Выход:
fieldA: 3
fieldB: 1
fieldC: 5
fieldD: 12345
fieldE: 9
C
typedef struct _MyHeader {
unsigned char fieldA : 3;
unsigned char fieldB : 2;
unsigned char fieldC : 3;
unsigned short fieldD : 14;
unsigned char fieldE : 4;
} MyHeader, *pMyHeader;
int set_header(pMyHeader hdr) {
hdr->fieldA = 3;
hdr->fieldB = 1;
hdr->fieldC = 5;
hdr->fieldD = 12345;
hdr->fieldE = 9;
return(0);
}