在施法时跳过字节

时间:2017-06-01 05:06:09

标签: c++ struct byte field

我有一个看起来像这样的结构

struct message_header
{
    unsigned long msg_num : 32;            //0-3    message id
    unsigned long msg_len : 32;            //4-7    message length
    unsigned long hardware_version : 16;   //8-9    hardware version
    unsigned long sender_location : 32     //10-13  location
    unsigned long message;                 //14 ... messages
};

message_header * msg_ptr;

recvbuf函数接收到字符数组(recvfrom)后,我会这样做 reinterpret_cast

msg_ptr = reinterpret_cast<message_header*>(recvbuf)

然而,在我的模拟器(来自linux,VM)发送数据和我的接收器(结构在接收器中)(在Windows上)之后,输出数据不符合。

假设从模拟器发送的数据是:

msg num : 1010
msg len : 20
hardware version: 1
location: 25
messages: //rest of the bytes

来自wireshark的数据包显示:

00 00 03 F2
00 00 00 14
00 01 00 00
00 19 00 00
...

输出打印是:

msg num : 1010
msg len : 20
hardware version: 1
location: 1638400

经过多次调试后,我注意到在演员表中,在硬件版本之后,00 00之后的01被丢弃或被跳过,我不知道哪一个我找不到确定它的方法,00 19 00 00的接下来的4个字节被投射到我的sender_location

发件人的所有邮件类型和长度都是根据发件人的设计规范构建的,发件人的hardware versionunsigned short

我已阅读以下问题和答案

Fields in a struct skipping bytes

#pragma pack effect

我试过但无济于事,请指教。

1 个答案:

答案 0 :(得分:0)

  

成员的对齐将位于边界上,该边界是n的倍数或成员大小的倍数,以较小者为准。

我一开始并不明白这意味着什么,直到我一遍又一遍地重读,我才意识到我的hardware version正在使用long 4 bytes,而不是我应该使用short 2 bytes来代替另一个问题,这就是为什么位域限制不起作用,或者我可能错误地理解它。

因此,在将其从long更改为short以及使用#pragma pack(1)后,该广告系列现在运行正常。

我发现的方法是使用offsetof函数来检查

cout << offsetof (message_header, msg_num) << endl;
cout << offsetof (message_header, msg_len) << endl;
cout << offsetof (message_header, hardware_version) << endl;
cout << offsetof (message_header, sender_location ) << endl;
cout << offsetof (message_header, message) << endl;

打印输出,然后我意识到位域根本不起作用。
0
4
8
12
16

更改hardware_version后,从long更改为short,而没有#pragma pack(1),打印输出仍然与上面的相似,但是,#pragma pack(1)已启用,打印输出

0
4
6
10
14