Python ctype Structure/Union 问题
Python ctype Structure/Union Issue
所以我想做一个位图。数据以 32 位数字的形式来自设备,每一位都代表某种意义。所以我在玩 ctype 结构和联合。尝试执行经典的 int in 并将其映射到各个位。
from ctypes import *
class Bits(Structure):
_fields_ = [("Bit_0", c_bool),
("Bit_1", c_bool),
("Bit_2", c_bool),
("Bit_3", c_bool),
("Bit_4", c_bool),
("Bit_5", c_bool),
("Bit_6", c_bool),
("Bit_7", c_bool),
("Bit_8", c_bool),
("Bit_9", c_bool),
("Bit_10", c_bool),
("Bit_11", c_bool),
("Bit_12", c_bool),
("Bit_13", c_bool),
("Bit_14", c_bool),
("Bit_15", c_bool),
("Bit_16", c_bool),
("Bit_17", c_bool),
("Bit_18", c_bool),
("Bit_19", c_bool),
("Bit_20", c_bool),
("Bit_21", c_bool),
("Bit_22", c_bool),
("Bit_23", c_bool),
("Bit_24", c_bool),
("Bit_25", c_bool),
("Bit_26", c_bool),
("Bit_27", c_bool),
("Bit_28", c_bool),
("Bit_29", c_bool),
("Bit_30", c_bool),
("Bit_31", c_bool),
]
def return_dic(self):
dic = {}
for field in self._fields_:
dic[field[0]] = getattr(self, field[0])
return(dic)
class Int(Structure):
_fields_ = [("Value", c_int32)]
class union(Union):
_fields_ = [("Descriptor", Int),("Bits", Bits)]
test = union(Int(0b01111111111111111111111111111111))
print("{0:b}".format(test.Descriptor.Value))
dic = test.Bits.return_dic()
for x in dic.keys():
print("{0} : {1:b}".format(x,dic[x]))
和这个输出。第一行是 32 位值,其余是单独的位。
1111111111111111111111111111111
Bit_0 : 1
Bit_1 : 1
Bit_2 : 1
Bit_3 : 1
Bit_4 : 0
Bit_5 : 0
Bit_6 : 0
Bit_7 : 0
Bit_8 : 0
Bit_9 : 0
Bit_10 : 0
Bit_11 : 0
Bit_12 : 0
Bit_13 : 0
Bit_14 : 0
Bit_15 : 0
Bit_16 : 0
Bit_17 : 0
Bit_18 : 0
Bit_19 : 0
Bit_20 : 0
Bit_21 : 0
Bit_22 : 0
Bit_23 : 0
Bit_24 : 0
Bit_25 : 0
Bit_26 : 0
Bit_27 : 0
Bit_28 : 0
Bit_29 : 0
Bit_30 : 0
Bit_31 : 0
为什么第 4 - 31 位没有被设置?位 0 - 3 也表现得很奇怪
c_bool
是一个字节大小,打印 0
表示零,1
表示非零。您可以看到结构的字节大小不正确:
>>> sizeof(Bits)
32
>>> sizeof(Int)
4
>>> sizeof(union)
32
由于 Value
是一个 4 字节整数,并且所有四个字节都非零,联合打印中的前四个字节大小的 c_bool
字段 1
.
要正确指定位字段,请指定第三个参数以及要使用的位数。参见 Bit fields in structures and unions in the ctypes documentation。
from ctypes import *
class Bits(Structure):
_fields_ = [('Bit_0', c_uint32, 1), # Use 1 bit of an unsigned 32-bit integer.
('Bit_1', c_uint32, 1), # etc.
('Bit_2', c_uint32, 1),
('Bit_3', c_uint32, 1),
('Bit_4', c_uint32, 1),
('Bit_5', c_uint32, 1),
('Bit_6', c_uint32, 1),
('Bit_7', c_uint32, 1),
('Bit_8', c_uint32, 1),
('Bit_9', c_uint32, 1),
('Bit_10', c_uint32, 1),
('Bit_11', c_uint32, 1),
('Bit_12', c_uint32, 1),
('Bit_13', c_uint32, 1),
('Bit_14', c_uint32, 1),
('Bit_15', c_uint32, 1),
('Bit_16', c_uint32, 1),
('Bit_17', c_uint32, 1),
('Bit_18', c_uint32, 1),
('Bit_19', c_uint32, 1),
('Bit_20', c_uint32, 1),
('Bit_21', c_uint32, 1),
('Bit_22', c_uint32, 1),
('Bit_23', c_uint32, 1),
('Bit_24', c_uint32, 1),
('Bit_25', c_uint32, 1),
('Bit_26', c_uint32, 1),
('Bit_27', c_uint32, 1),
('Bit_28', c_uint32, 1),
('Bit_29', c_uint32, 1),
('Bit_30', c_uint32, 1),
('Bit_31', c_uint32, 1)]
def return_dic(self):
dic = {}
for field in self._fields_:
dic[field[0]] = getattr(self, field[0])
return(dic)
class Int(Structure):
_fields_ = [('Value', c_uint32)]
class union(Union):
_fields_ = [('Descriptor', Int),('Bits', Bits)]
test = union(Int(0x87654321))
print('{0:b}'.format(test.Descriptor.Value))
dic = test.Bits.return_dic()
for x in dic.keys():
print('{0} : {1:b}'.format(x,dic[x]))
输出:
10000111011001010100001100100001
Bit_0 : 1
Bit_1 : 0
Bit_2 : 0
Bit_3 : 0
Bit_4 : 0
Bit_5 : 1
Bit_6 : 0
Bit_7 : 0
Bit_8 : 1
Bit_9 : 1
Bit_10 : 0
Bit_11 : 0
Bit_12 : 0
Bit_13 : 0
Bit_14 : 1
Bit_15 : 0
Bit_16 : 1
Bit_17 : 0
Bit_18 : 1
Bit_19 : 0
Bit_20 : 0
Bit_21 : 1
Bit_22 : 1
Bit_23 : 0
Bit_24 : 1
Bit_25 : 1
Bit_26 : 1
Bit_27 : 0
Bit_28 : 0
Bit_29 : 0
Bit_30 : 0
Bit_31 : 1
所以我想做一个位图。数据以 32 位数字的形式来自设备,每一位都代表某种意义。所以我在玩 ctype 结构和联合。尝试执行经典的 int in 并将其映射到各个位。
from ctypes import *
class Bits(Structure):
_fields_ = [("Bit_0", c_bool),
("Bit_1", c_bool),
("Bit_2", c_bool),
("Bit_3", c_bool),
("Bit_4", c_bool),
("Bit_5", c_bool),
("Bit_6", c_bool),
("Bit_7", c_bool),
("Bit_8", c_bool),
("Bit_9", c_bool),
("Bit_10", c_bool),
("Bit_11", c_bool),
("Bit_12", c_bool),
("Bit_13", c_bool),
("Bit_14", c_bool),
("Bit_15", c_bool),
("Bit_16", c_bool),
("Bit_17", c_bool),
("Bit_18", c_bool),
("Bit_19", c_bool),
("Bit_20", c_bool),
("Bit_21", c_bool),
("Bit_22", c_bool),
("Bit_23", c_bool),
("Bit_24", c_bool),
("Bit_25", c_bool),
("Bit_26", c_bool),
("Bit_27", c_bool),
("Bit_28", c_bool),
("Bit_29", c_bool),
("Bit_30", c_bool),
("Bit_31", c_bool),
]
def return_dic(self):
dic = {}
for field in self._fields_:
dic[field[0]] = getattr(self, field[0])
return(dic)
class Int(Structure):
_fields_ = [("Value", c_int32)]
class union(Union):
_fields_ = [("Descriptor", Int),("Bits", Bits)]
test = union(Int(0b01111111111111111111111111111111))
print("{0:b}".format(test.Descriptor.Value))
dic = test.Bits.return_dic()
for x in dic.keys():
print("{0} : {1:b}".format(x,dic[x]))
和这个输出。第一行是 32 位值,其余是单独的位。
1111111111111111111111111111111
Bit_0 : 1
Bit_1 : 1
Bit_2 : 1
Bit_3 : 1
Bit_4 : 0
Bit_5 : 0
Bit_6 : 0
Bit_7 : 0
Bit_8 : 0
Bit_9 : 0
Bit_10 : 0
Bit_11 : 0
Bit_12 : 0
Bit_13 : 0
Bit_14 : 0
Bit_15 : 0
Bit_16 : 0
Bit_17 : 0
Bit_18 : 0
Bit_19 : 0
Bit_20 : 0
Bit_21 : 0
Bit_22 : 0
Bit_23 : 0
Bit_24 : 0
Bit_25 : 0
Bit_26 : 0
Bit_27 : 0
Bit_28 : 0
Bit_29 : 0
Bit_30 : 0
Bit_31 : 0
为什么第 4 - 31 位没有被设置?位 0 - 3 也表现得很奇怪
c_bool
是一个字节大小,打印 0
表示零,1
表示非零。您可以看到结构的字节大小不正确:
>>> sizeof(Bits)
32
>>> sizeof(Int)
4
>>> sizeof(union)
32
由于 Value
是一个 4 字节整数,并且所有四个字节都非零,联合打印中的前四个字节大小的 c_bool
字段 1
.
要正确指定位字段,请指定第三个参数以及要使用的位数。参见 Bit fields in structures and unions in the ctypes documentation。
from ctypes import *
class Bits(Structure):
_fields_ = [('Bit_0', c_uint32, 1), # Use 1 bit of an unsigned 32-bit integer.
('Bit_1', c_uint32, 1), # etc.
('Bit_2', c_uint32, 1),
('Bit_3', c_uint32, 1),
('Bit_4', c_uint32, 1),
('Bit_5', c_uint32, 1),
('Bit_6', c_uint32, 1),
('Bit_7', c_uint32, 1),
('Bit_8', c_uint32, 1),
('Bit_9', c_uint32, 1),
('Bit_10', c_uint32, 1),
('Bit_11', c_uint32, 1),
('Bit_12', c_uint32, 1),
('Bit_13', c_uint32, 1),
('Bit_14', c_uint32, 1),
('Bit_15', c_uint32, 1),
('Bit_16', c_uint32, 1),
('Bit_17', c_uint32, 1),
('Bit_18', c_uint32, 1),
('Bit_19', c_uint32, 1),
('Bit_20', c_uint32, 1),
('Bit_21', c_uint32, 1),
('Bit_22', c_uint32, 1),
('Bit_23', c_uint32, 1),
('Bit_24', c_uint32, 1),
('Bit_25', c_uint32, 1),
('Bit_26', c_uint32, 1),
('Bit_27', c_uint32, 1),
('Bit_28', c_uint32, 1),
('Bit_29', c_uint32, 1),
('Bit_30', c_uint32, 1),
('Bit_31', c_uint32, 1)]
def return_dic(self):
dic = {}
for field in self._fields_:
dic[field[0]] = getattr(self, field[0])
return(dic)
class Int(Structure):
_fields_ = [('Value', c_uint32)]
class union(Union):
_fields_ = [('Descriptor', Int),('Bits', Bits)]
test = union(Int(0x87654321))
print('{0:b}'.format(test.Descriptor.Value))
dic = test.Bits.return_dic()
for x in dic.keys():
print('{0} : {1:b}'.format(x,dic[x]))
输出:
10000111011001010100001100100001
Bit_0 : 1
Bit_1 : 0
Bit_2 : 0
Bit_3 : 0
Bit_4 : 0
Bit_5 : 1
Bit_6 : 0
Bit_7 : 0
Bit_8 : 1
Bit_9 : 1
Bit_10 : 0
Bit_11 : 0
Bit_12 : 0
Bit_13 : 0
Bit_14 : 1
Bit_15 : 0
Bit_16 : 1
Bit_17 : 0
Bit_18 : 1
Bit_19 : 0
Bit_20 : 0
Bit_21 : 1
Bit_22 : 1
Bit_23 : 0
Bit_24 : 1
Bit_25 : 1
Bit_26 : 1
Bit_27 : 0
Bit_28 : 0
Bit_29 : 0
Bit_30 : 0
Bit_31 : 1