2015-03-02 72 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在它所属的类内。它还允许从多个流输入缓冲区组装消息。

我不是静态方法的粉丝。与反序列化相关的协议状态数据应该是每个实例,(线程安全)。