发生铸造时的字节跳过

Byte skipping when casting occurs

本文关键字:字节      更新时间:2023-10-16

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

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;

recvfrom函数接收字符阵列(recvbuf(后,我会做 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

经过大量调试后,我注意到在演员阵容,硬件版本之后,丢弃或跳过01之后的00 00,我不确定我找不到哪种方法来确定它,以及下一个00 19 00 00的4个字节被施加到我的sender_location中。

发件人的所有消息类型和长度都是在发件人的设计规范上构建基础,并且发件人上的hardware versionunsigned short

我已经阅读了以下问题和答案

在结构跳过字节中的字段

#pragma pack效果

我尝试过,但无济于事,请建议。

构件的比对将位于n的倍数或成员大小的倍数上,以较小者为准。

我一开始不明白这意味着什么,直到我一遍又一遍地重新阅读,我意识到我的hardware version正在使用4 byteslong,而不是我应该使用2 bytesshort,而是另一个问题来了在想到,这就是为什么比特菲尔德限制不起作用,或者我可能错误地理解它。

因此,在将其从long更改为short之后,并且使用#pragma pack(1),Cast现在可以正常工作。

以及我如何发现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更改为longshort,并且没有#pragma pack(1),打印输出仍然与上述一个相似,但是,一旦启用了#pragma pack(1),则打印输出,打印输出为

0
4
6
10
14