ctypes结构,字节对齐

时间:2018-01-26 08:16:28

标签: python ubuntu ctypes

我正在使用ctypes模块来定义类似C的结构。

    class AtomPayload(ctypes.LittleEndianStructure):
        _pack_ = 1
        _fields_ = [ ("address",    ctypes.c_uint8,  8),
             ("mask",       ctypes.c_uint8,  3),
             ("regL",       ctypes.c_uint8,  5),
             ("regH",       ctypes.c_uint8,  1),
             ("rw",         ctypes.c_uint8,  1),
             ("reserved",   ctypes.c_uint8,  6),
             ("param1",     ctypes.c_int32, 16),
             ("param2",     ctypes.c_int32, 16),
             ("param3",     ctypes.c_int16, 16)]

但是这个结构的大小在Windows和Ubuntu中有不同的结果。

在Ubuntu中,输出为10,而它是9,这是我想要的Windows。任何人都知道如何使它也在Ubuntu中工作。 pack 属性在Ubuntu中不起作用吗?

1 个答案:

答案 0 :(得分:0)

如果我像这样测试你的例子(在ubuntu上):

import codecs
p = AtomPayload()
p.param1 = 0x1111
p.param2 = 0x2222
p.param3 = 0x3333
print(codecs.encode(bytes(p), 'hex'))

它产生:

b'00000011110022220000'

我不确定这里到底发生了什么,这可能是ctypes中的一个错误。可能是由未对齐的位域引起的问题。

无论如何,将32位位域分成两个16位整数对我来说似乎没必要,这应该会产生相同的结果:

class AtomPayload(ctypes.LittleEndianStructure):
        _pack_ = 1
        _fields_ = [
             ("address",    ctypes.c_uint8,  8),
             ("mask",       ctypes.c_uint8,  3),
             ("regL",       ctypes.c_uint8,  5),
             ("regH",       ctypes.c_uint8,  1),
             ("rw",         ctypes.c_uint8,  1),
             ("reserved",   ctypes.c_uint8,  6),
             ("param1",     ctypes.c_int16, 16),
             ("param2",     ctypes.c_int16, 16),
             ("param3",     ctypes.c_int16, 16)]

现在我明白了:

b'000000111122223333'