2017-06-01 60 views
-1

我有一个结构,看起来像这样字节铸造时跳过发生

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)发送数据和我的接收器(结构在接收器中)之后(在窗口上)之后,输出数据不符合。

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

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

包表示:

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被丢弃或跳过了,我不确定哪一个,因为我找不到方法来确定它,而接下来的4个00 19 00 00的字节被投入我的sender_location

发件人的所有消息类型和长度均基于发件人的设计规范构建,而发件人的hardware versionunsigned short

我有以下问题念起来和答案

Fields in a struct skipping bytes

#pragma pack effect

,我已经尝试过,但都无济于事,请告知。

+0

是否使用旧的编译器不支持[C99固定宽度的整数类型](http://en.cppreference.com/w/c/types/整数)还是可以打包结构?有没有其他的理由你有一个位域? –

+0

我正在使用VS 2015,并且我使用位域来限制每个变量的字节数,我是一名初级程序员,使用位域是由我的高级“推荐”,我最初使用的是每个域的memcpy,但是被告知把它转换成一个结构并不复杂。 – Zac

+0

至于你的问题,你是否试图分别分配消息结构,然后使用'memcpy'来复制数据(整个结构)? –

回答

0

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

我不明白这是什么意思,在第一,直到我重新读一遍又一遍,我才知道我的hardware version使用的4 bytes一个long,而不是我应该使用2 bytesshort相反,想到另一个问题,这就是为什么位域限制不起作用,或者我可能错误地理解了它。

因此,在将其从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,从longshort后,没有#pragma pack(1),打印输出仍然是类似于上面的一个,然而,一旦#pragma pack(1)被启用,打印输出是

0
4
6
10
14