2015-03-02 68 views
0

我想序列化/反序列化一些結構化數據,以便通過char* buffer通過網絡發送它。C++中的對象序列化

更確切地說,假設我有一個類型爲struct Message的消息。

struct Message { 
     Header header; 
     Address address; 
     size_t size; // size of data part 
     char* data; 
    } message 

在C中,我會用一些諸如:

size = sizeof(Header) + sizeof(Address) + sizeof(size_t) + message.size; 
    memcpy(buffer, (char *) message, size); 

序列化,並

Message m = (Message) buffer; 

反序列化。

什麼是「正確」的方式在C++中做到這一點。定義一個類而不是一個結構會更好嗎?我應該超載一些操作員嗎?是否有對齊問題需要考慮?

編輯:感謝指出「char *」的問題。提供的C版本不正確。應該單獨複製data字段指向的數據部分。

+1

什麼阻止你在C++中做同樣的事情?除了你似乎沒有序列化'data'字段,並且不考慮結構填充之類的事實。 – 2015-03-02 17:38:31

+0

你不會直接通過C中的網絡發送該結構。嘗試一下,看看你是否沒有垃圾或段錯誤。 (沒有特別的安排,存儲在'data'中的地址在創建它的過程之外沒有任何意義。) – cHao 2015-03-02 17:39:42

+0

「在C中,我會使用諸如......的東西」而且你會錯誤的。'sizeof(struct Message)'是可讀的,可維護的*和*正確的。你的三個大小的總和既不是。 – 2015-03-02 17:40:09

回答

2

其實有許多種:

可以提高讓它爲你做:http://www.boost.org/doc/libs/1_52_0/libs/serialization/doc/tutorial.html

重載流運營商<<系列化和>>反序列化與文件工作得很好,字符串流

你可以指定一個構造函數Message(const char *)來構造char *。

我的靜態方法風扇反序列化,如:

Message { 
    ... 
    static bool desirialize (Message& dest, char* source); 
} 

因爲你可以反序列化時,直接捕獲錯誤。

並且當您在評論中應用修改時,您建議的版本是可以的。

+1

我會*高度*推薦「讓序列化庫爲你做」的路線,除非你有一個非常好的理由不要。有很多邊緣情況下,當你推出自己的產品時,你必須掩飾錯誤的概率很高。 – aruisdante 2015-03-02 17:55:32

0

爲什麼不在你的繼承樹中插入一個虛擬的'NetworkSerializable'類? 'void NetSend(fd socket)'方法會發送內容(不會公開任何私有數據),'int(bufferClass buffer)'可能返回-1,如果沒有完整的有效消息被激活,或者如果有效的消息有已經組裝好了,'緩衝區'中未使用的字符的數量。

這封裝所有的組裝/反彙編協議狀態變量和其他gunge在它所屬的類內。它還允許從多個流輸入緩衝區組裝消息。

我不是靜態方法的粉絲。與反序列化相關的協議狀態數據應該是每個實例,(線程安全)。