2016-07-28 75 views
0

我有以下結構:複製結構一個字節的緩衝區內

struct sample { 
    uint8_t four; 
    bool b; 
    uint8_t two; 
}; 

爲了發送一個UDP包,我需要將這些值打包到一個單字節:

| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 
+---+---+---+---+---+---+---+---+ 
|  four  | 0 | b | two | 
+---------------+---+---+-------+ 

什麼複製此字節中的結構值的最佳方法是什麼?我在做這件事之前檢查了前提條件,因此在將uint8_t值複製到更少的空間時不會丟失任何數據。

回答

5

我只想用一個函數:

uint8_t pack(const sample &s) 
{ 
    return (s.four & 0xF) | (s.b << 5) | ((s.two & 3) << 6); 
} 

,你說,數據範圍檢查,你可以簡化到:

return s.four | (s.b << 5) | (s.two << 6); 
2

因爲你的代碼是不可移植的反正,你可能也僅僅使用位字段位置:

struct sample { 
    uint8_t four:4; 
    bool empty:1; 
    bool b:1; 
    uint8_t two:2; 
}; 

我不是位字段的球迷,但他們似乎是適合你的情況。

+1

在'b'之前不應該'empty'嗎? – Slava

+0

@Slava,當然。固定,thx。 – SergeyA

+1

爲什麼不能攜帶? – Jepessen

0

你的位順序以顯示獨特的...辦法。通常當我們用二進制表示值時,低位顯示在右邊。只要你打包和解包數據,你可以選擇你的位次序。不過請注意網絡訂單與系統訂單。雖然每個平臺上的字節中的位順序相同,但字節順序中的字可以更改。

您必須知道您的應用程序以確定打包/拆包是否值得您付出努力。在每一方都有更多的計算,並且取決於UDP數據包之間的間隔和每個UDP數據包中打包的數據量,這可能不值得。如果你只是想爲移動應用程序保存數據,那麼謝謝你:@)

我總是避免由於平臺/編譯器偏執狂而導致的布爾變換。可以使用類似s.b?32:0的東西來代替。

+0

我試圖創建CIGI數據包,並且標準有很多數據包以這種方式構建... – Jepessen

+0

對不起,有點大腦失誤。網絡數據包總是以這種方式寫入 –