2017-06-01 65 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