簡體   English   中英

序列化/反序列化 c++ 中的位域結構

[英]Serializing/deserializing a bitfield structure in c++

我有一個

typedef struct {
    uint32_t  Thread: HTHREAD_BUS_WIDTH; 
    uint32_t Member: 3;                  
    uint32_t Proxy:3;  
// Other members, fill out 32 bits                 
} MyStruct;

我必須從一個系統傳輸到另一個系統作為包含 32 位字的緩沖區的一項。

序列化結構以及反序列化它的最佳方法是什么? “最佳”在這里意味着安全鑄造,沒有不必要的復制。 對於一個鑄造方向,我發現(作為成員函數)

int &ToInt() {
    return *reinterpret_cast<int *>(this);}

是否有類似的有效轉換,即從 integer 到 MyStruct; 最好的成員是 function?

如何定義哪個位表示哪個字段? (甚至可能是反序列化發生在另一個程序、另一種語言、小/大端系統中?

如何定義哪個位表示哪個字段?

你不能。 您無法控制位域的布局。

“最佳”在這里意味着安全鑄造,沒有不必要的復制。

沒有可以避免復制的便攜式安全演員。


序列化位域的一種可移植方法是按所需順序手動轉換為 integer。 例如:

MyStruct value = something;
uint32_t out = 0;
out |= value.Thread;
out << HTHREAD_BUS_WIDTH;
out |= value.Member;
out << 3;
out |= value.Proxy;

在所示示例中,最低有效位包含字段Proxy ,而其他字段在更高有效位中相鄰。

當然,為了正確序列化這個生成的 integer,就像序列化任何 integer 一樣,您必須考慮字節順序。 integer 的序列化可以通過重復移動 integer 並將字節按重要性順序復制到數組中來實現。

如果您需要從可能具有不同字節順序的其他系統讀取,則不能依賴可移植位域。 一種解決方案是“擴展”您的結構,以便每個字段在“傳輸”緩沖區中序列化為 32 位值。 一個安全的實現可能是這樣的:

typedef struct {
    uint32_t  Thread: HTHREAD_BUS_WIDTH; 
    uint32_t Member: 3;                  
    uint32_t Proxy:3;  
// Other members, fill out 32 bits                 
   std::vector<uint32_t > to_buffer() const;
} MyStruct;

to_buffer()的實現:

std::vector<uint32_t > MyStruct::to_buffer() const
{
   std::vector<uint32_t> buffer;
   buffer.push_back((uint32_t )(Thread);
   buffer.push_back((uint32_t )(Member);
   buffer.push_back((uint32_t )(Proxy);
   // push other members

  return buffer;
}

然后在接收端你可以做“緩沖區”來構建。

如果您不想擴展不使用 32 位的字段,您始終可以通過移位和屏蔽位來實現自己的打包 function,例如:

uint32_t menber_and_procy = (Member << 3) | proxy; // and so one for other members.

它更容易出錯。

根據我自己的經驗,如果通信帶寬不是問題,那么依靠“類似文本”的內容是更好的選擇(沒有字節序問題並且非常容易調試)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM