序列化是指将任意的数据结构可逆的解构到字节流中。序列化之后我们就可以实现对象的持久化,网络传输,远程参数传递等。序列化在网络传输中是非常重要的。
在定义网络结构包时,我们可能通常会以以下方式去处理序列化问题,如:
class CBasePacket
{
...
...
public:
virtual void readFromBuffer(const char* pBuffer)=0;
virtual void writeToBuffer(char* pBufffer)=0;
virtual int getBufferSize(){return 0;};
}
这是一个基类,包含以上几个重要的虚函数,派生类可以通过实现该基类自己去实现几个方法,主要作用就是序列化和反序列化。
对于新定义的网络数据包,你需要如下实现,假设定义一个TestPacket
class TestPacket : public CBasePacket
{
...
...
public:
int m_id;
std::string m_strName;
bool m_bSend;
};
void TestPacket::readFromBuffer(const char* pBuffer)
{
const char* pTemp = pBuffer;
memcpy(&m_id,pTemp,sizeof(m_id));
pTemp += sizeof(m_id);
memcpy(&m_strName,pTemp,sizeof(m_strName));
pTemp += sizeof(m_strName);
memcpy(&m_bSend,pTemp,sizeof(m_bSend));
pTemp += sizeof(m_bSend);
}
void TestPacket::writeToBuffer(char* pBuffer)
{
char* pTemp = pBuffer ;
memcpy(pTemp,&m_id,sizeof(m_id));
pTemp+=sizeof(m_id);
memcpy(pTemp,&m_strName,sizeof(m_strName));
pTemp+=sizeof(m_strName);
memcpy(pTemp,&m_bSend,sizeof(m_bSend));
pTemp+=sizeof(m_bSend);
}
int TestPacket::getBufferSize()
{
return sizeof(m_id) + sizeof(m_strName) + sizeof(m_bSend);
}
对于包结构比较复杂的情况,编写readFromBuffer和writeToBuffer容易出错,而一旦出问题,将很难发现;虽然在单元测试阶段可以提前预知这类问题,但对于复杂结构,即使出现问题,可能花长时间才能发现问题所在;
Boost C++库是一组基于C++标准的现代库,可以很方便的集成到C++项目中,提供了对Windows和Linux等不同系统下的支持。Boost C++ 的序列化库允许将 C++ 应用程序中的对象转换为一个字节序列, 此序列可以被保存,并可在将来恢复对象的时候再次加载。Boost提供的序列化库可以很好的解决以上序列化缺点。
在Boost的序列化系统中,archive一词代表字节流的抽象。它可以是二进制格式,文本格式,XML格式,或用户自定义的格式。以下就是Boost提供的序列化基本的代码方式:
class Demo
{
public:
Demo()
{
b = false;
ch = 'a';
s = 34;
i = 1024;
l = 314L;
f = 3.14;
t = 100;
}
public:
bool b;
char ch;
short s;
int i;
long l;
double f;
time_t t;
// 侵入式类的写法
public:
template<class Archive>
Archive& serialize(Archive& ar, const unsigned int version)
{
return ar & b &ch & s & i & l & f & t;
}
};
// 非侵入式写法
template<class Archive>
Archive& serialize(Archive& ar, const user_defined& ud, const unsigned int version)
{
return ar & ud.b & ud.ch & ud.s & ud.i & ud.l & ud.f & ud.t;
}
根据代码可以看出Boost提供的序列化方法十分的简洁美观。另外,Boost不仅对基本类型,标准容器进行支持,还对Boost中的类型、Boost容器进行部分支持。如果考虑兼容Boost整套数据结构,可以考虑使用Boost的序列化。