2013-08-06 90 views
2

我想解压一个C结构,以二进制形式交给我的Python程序,并包含另一个嵌套结构。 C头的相关部分看起来是这样的:在Python中解压缩嵌套的C结构

typedef struct { 
    uint8_t seq; 
    uint8_t type; 
    uint16_t flags; 
    uint16_t upTimestamp; 
}__attribute__ ((packed)) mps_packet_header; 

typedef struct { 
    mps_packet_header header; 
    int16_t x[6]; 
    int16_t y[6]; 
    int16_t z[6]; 
    uint16_t lowTimestamp[6]; 
}__attribute__((packed)) mps_acc_packet_t; 
typedef mps_acc_packet_t accpacket_t; 

现在,在我的Python程序,我想用struct.unpack解包的accpacket。但是,我不知道解包的格式字符串应该是什么,因为accpacket包含嵌套的mps_packet_header。我曾尝试只是插入了mps_packet_header格式字符串开头,然后用accpacket的其余部分继续:

s = struct.Struct('= B B H H 6h 6h 6h H') 
seq, _type, flags, upTimestamp, x, y, z, lowTimestamp = s.unpack(packet_data) 

然而,这显然是不正确;格式字符串的calcsize为44,而结构本身的大小为54.

如何为此结构制定正确的格式字符串?

回答

2
  1. Struct格式与C结构不匹配。 (最终H应该是6H
  2. struct.unpack(6h,..)确实返回6个字段。 (不是一个6个元素)

所以,你的代码应该貌似..

s = struct.Struct('= B B H H 6h 6h 6h 6H') 
fields = s.unpack(packet_data) 
seq, _type, flags, upTimestamp = fields[:4] 
x = fields[4:10] 
y = fields[10:16] 
z = fields[16:22] 
lowTimestamp = fields[22:] 
+0

良好的渔获物;我错过了最后的量词。随着那个''.size'给出54。 –

2

您可以尝试构建http://construct.readthedocs.io/en/latest/

import construct as cstruct 
def mps_packet_header(name): 
    return cstruct.Struct(
     name, 
     cstruct.UNInt8('seq'), 
     cstruct.UNInt8('type'), 
     cstruct.UNInt16('flags'), 
     cstruct.UNInt16('upTimestamp'), 
    ) 

mps_acc_packet_t = cstruct.Struct(
    'mps_acc_packet_t', 
    mps_packet_header('header') 
    cstruct.Array(6, cstruct.NInt16('x')), 
    cstruct.Array(6, cstruct.NInt16('y')), 
    cstruct.Array(6, cstruct.NInt16('z')), 
    cstruct.Array(6, cstruct.UNInt16('lowTimestamp')), 
) 

accpacket_t = mps_acc_packet_t 
... 
... 
packet_data = .... 
packet = accpacket_t.parse(packet_data) 
print(packet) 
print(packet.header) 
print(packet.x, packet.y, packet.z)