2014-01-13 75 views
12

我正在嘗試讀取二進制文件。問題在於文件的創建者沒有花時間將數據結構與其自然邊界進行適當對齊,並且所有內容都緊湊。這使得使用C++結構很難讀取數據。強制C++結構緊緊包裝

有沒有辦法迫使struct包裝嚴密?

實施例:

struct { 
    short a; 
    int b; 
} 

上述結構是8個字節:2 short a,2填充,4 int b。但是,在磁盤上,數據只有6個字節(沒有用於對齊的2個字節的填充)

請注意實際的數據結構是數千字節和許多字段,包括一對數組,所以我寧願不要單獨閱讀每個字段。

+1

查看包裝結構。請注意,某些體系結構需要對齊才能正確讀取結構。 –

+0

http://en.cppreference.com/w/cpp/language/alignas says'alignas(0)has no effect'? –

+0

'#pragma pack'可能有幫助。 – Jarod42

回答

13

如果你使用GCC,你可以做struct __attribute__ ((packed)) { short a; int b; }

在VC++中,你可以做#pragma pack(1)。該選項是also supported by GCC

#pragma pack(push, 1) 
struct { short a; int b; } 
#pragma pack(pop) 

其他編譯器可能有選項來做沒有填充的結構的緊密包裝。

+0

謝謝。我目前正在使用GCC並且工作。在我們改變編譯器的時候,我留下了關於編譯指示的評論。 – steveo225

6

您需要使用編譯器特定的非標準僞指令來指定1字節的打包。如在Windows下:

#pragma pack (push, 1) 

的問題是,該文件的創建者沒有采取任何時間好好 字節對齊數據結構,一切都擠得人貼人。

其實,設計師做的是正確的事情。填充是標準說的可以應用的東西,但是它並沒有說明在什麼情況下應該填充多少填充。該標準甚至沒有說出一個字節中有多少位。即使你可能認爲即使這些東西沒有被指定,它們在現代機器上仍然應該具有相同的合理價值,但事實並非如此。例如,在32位Windows機器上,填充可能是一件事,而在64位版本的Windows上可能是另一回事。也許它會是一樣的 - 那不是重點。關鍵是你不知道在不同系統上填充的內容。因此,通過「包裝它」,開發人員做了他們唯一可以做的事情 - 使用一些包裝,他可以合理確信每個系統都能夠理解。在那種情況下,通常理解的包裝是在保存到磁盤或發送電線的結構中不使用填充。

+1

我的意思是,結構元素的排列順序可以更好地排列,這樣在許多不同的情況下排列就會很好。並不是說他們只是簡單地打包字節。 – steveo225