我没有对此进行严格测试,但它似乎适用于无符号类型(编辑:它也适用于有符号字节/短类型)。
编辑2:这真的是命中注定。这取决于库的编译器将位打包到结构中的方式,这不是标准化的。例如,对于 gcc 4.5.3,只要我不使用该属性来打包结构,它就可以工作,即__attribute__ ((__packed__))
(因此,它不是 6 个字节,而是被打包成 4 个字节,您可以使用__alignof__
and进行检查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);
}