6

Python プログラムにバイナリ形式で渡され、ネストされた別の構造体を含む C 構造体をアンパックしようとしています。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.unpackaccpacket. 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)

しかし、これは明らかに正しくありません。フォーマット文字列の acalcsizeは 44 ですが、構造体自体のサイズは 54 です。

この構造体の正しいフォーマット文字列を作成するにはどうすればよいですか?

4

2 に答える 2

4
  1. フォーマットがStructC 構造と一致しません。(最終的 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:]
于 2013-08-06T14:16:20.680 に答える
4

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)
于 2016-08-16T14:50:45.490 に答える