cereal是一个基于c++实现的序列化工具库,用于将c++的各种数据结构序列化成二进制流进行传输,并将二进制流反序列化成原来的数据结构。相比同用途库,cereal使用简单,仅需包含头文件,运行效率尚可,对比如下:
cereal的官方下载地址为:http://uscilab.github.io/cereal/index.html
编译源码过程很简单,在此不详述(注意源码解压在全英文路径下进行编译,不然出现编译失败的错误)。
使用cmake工具对源码进行编译和安装,选择对应版本的编译器和x86/x64选项,最终释放出一系列头文件到安装路径:
将cereal文件夹拷贝到指定位置,并设置系统环境变量为头文件所在路径,如:"D:\3rdLib\cereal\include"。
接下来就可以使用cereal库了~
cereal库的使用需要注意以下几点:
- 需要人工保证读写的archive版本相对应。
- 二进制存档可以通过包含
来使用,二进制归档不尝试确保在不同的体系结构之间保持endianness。如果您的数据将在小端和大端机器上读取,您应该使用 ,它跟踪保存和加载机器的endianness,并适当地转换数据。它的开销略高于常规的二进制存档。记住在构造流时指定二进制标志(std::ios::binary)。 - 在序列化每种类型之前和之后立即调用特殊函数,称为prologue and epilogue。
- 没有默认构造函数的类用loadAndConstruct
- 序列化函数:可以是类内部函数也可以是外部函数。既可以使用单独的序列化函数,也可以分开使用load和save或load_minimal和save_minimal对(例如,在加载类时动态分配内存),无需显示的告诉cereal,但是需要只使用其中一种。
- 注:save函数是const的
- 如果需要把serialize函数写成protected或者private,需要声明友元friend class cereal::access;,并包含头文件#include
#include
template void serialize(Archive & archive)//, const std::uint32_t /* version */); template { archive(mtl_file_name); archive(mat4); }
- 所有的STL类型都要相应的加上cereal/types/xxx.hpp的头文件,基础类型用cereal/types/base_class.hpp
- static成员要加details/static_object.hpp
————————————————
版权声明:本文为CSDN博主「_Lina」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_24634505/article/details/89534314
我分别测试了将一个结构体变量序列化成binary,xml和json的文件流和string流,并从文件流和string流中反序列化成原结构体变量,测试代码如下:
#include "cereal/archives/xml.hpp"
#include "cereal/archives/binary.hpp"
#include "cereal/archives/json.hpp"
#include "cereal/types/memory.hpp"
#include "cereal/types/base_class.hpp"
#include "cereal/types/vector.hpp"
#include
#include
#include
using namespace std;
typedef struct STRUCT_CEREAL
{
STRUCT_CEREAL()
{
templatePageNum = rand();
vecdata.push_back(rand() % 1024);
vecdata.push_back(rand() % 1024);
vecdata.push_back(rand() % 1024);
vecdata.push_back(rand() % 1024);
vecdata.push_back(rand() % 1024);
}
size_t templatePageNum;
vector vecdata;
// 下面的操作是为了在xml文件写入节点名字.
template
void serialize(Archive & ar)
{
ar(CEREAL_NVP(templatePageNum));
ar(CEREAL_NVP(vecdata));
}
//template
//void save(Archive & archive) const
//{
// cout << "save" << endl;
// archive(templatePageNum);
// archive(vecdata);
//}
//template
//void load(Archive & archive)
//{
// cout << "load" << endl;
// archive(templatePageNum);
// //archive(vecdata);
//}
}STRUCT_CEREAL;
ostream& operator<<(ostream& o, STRUCT_CEREAL& obj)
{
o << "templatePageNum=" << obj.templatePageNum << endl
<< "vecdata=\n";
for (size_t i = 0; i < obj.vecdata.size(); i++)
{
o << "vecdata[" << i << "]=" << obj.vecdata[i] << endl;
}
return o;
}
void test_cereal()
{
STRUCT_CEREAL stData;
cout << stData << endl;
/// binary.
// output to file.
ofstream out0;
{
out0.open("out.cereal", std::ios::binary);
cereal::BinaryOutputArchive archive(out0);
archive(stData);
}
out0.close();
STRUCT_CEREAL ttt0;
ifstream in0;
{
in0.open("out.cereal", ios::in);
cereal::BinaryInputArchive archive(in0);
archive(ttt0);
}
in0.close();
cout << ttt0 << endl;
// output to memory.
string strbuf0;
ostringstream outs0;
{
cereal::BinaryOutputArchive archive(outs0);
archive(stData);
}
cout << "outs0.str()=" << endl << outs0.str() << endl;
cout << "strbuf0=" << endl << strbuf0 << endl;
strbuf0 = outs0.str();
outs0.clear();
cout << "strbuf0=" << endl << strbuf0 << endl;
STRUCT_CEREAL ttts0;
string strbuff00;
istringstream ins0(strbuf0);
{
cereal::BinaryInputArchive archive(ins0);
archive(ttts0);
}
cout << "ttts0=" << endl << ttts0 << endl;
/// xml.
ofstream out1;
{
out1.open("./out.xml", ios::trunc); //ios::trunc表示在打开文件前将文件清空,由于是写入,文件不存在则创建
cereal::XMLOutputArchive archive(out1);
archive(stData);
}
out1.close();
ifstream in1;
STRUCT_CEREAL ttt1;
{
in1.open("./out.xml", ios::in);
cereal::XMLInputArchive archive(in1);
archive(ttt1);
}
in1.close();
cout << ttt1 << endl;
// output to memory.
string strbuf1;
ostringstream outs1;
{
cereal::XMLOutputArchive archive(outs1);
archive(stData);
}
cout << "outs1.str()=" << endl << outs1.str() << endl;
cout << "strbuf1=" << endl << strbuf1 << endl;
strbuf1 = outs1.str();
outs1.clear();
cout << "strbuf1=" << endl << strbuf1 << endl;
STRUCT_CEREAL ttts1;
string strbuff11;
istringstream ins1(strbuf1);
{
cereal::XMLInputArchive archive(ins1);
archive(ttts1);
}
cout << "ttts1=" << endl << ttts1 << endl;
/// json.
ofstream out2;
{
out2.open("./out.json", ios::trunc); //ios::trunc表示在打开文件前将文件清空,由于是写入,文件不存在则创建
cereal::JSONOutputArchive archive(out2);
archive(stData);
}
out2.close();
ifstream in2;
STRUCT_CEREAL ttt2;
{
in2.open("./out.json", ios::in);
cereal::JSONInputArchive archive(in2);
archive(ttt2);
}
in2.close();
cout << ttt2 << endl;
// output to memory.
string strbuf2;
ostringstream outs2;
{
cereal::JSONOutputArchive archive(outs2);
archive(stData);
}
cout << "outs2.str()=" << endl << outs2.str() << endl;
cout << "strbuf2=" << endl << strbuf2 << endl;
strbuf2 = outs2.str();
outs2.clear();
cout << "strbuf2=" << endl << strbuf2 << endl;
STRUCT_CEREAL ttts2;
string strbuff22;
istringstream ins2(strbuf2);
{
cereal::JSONInputArchive archive(ins2);
archive(ttts2);
}
cout << "ttts2=" << endl << ttts2 << endl;
cout << "running cereal finished!" << endl;
}
运行结果如下:
templatePageNum=41
vecdata=
vecdata[0]=35
vecdata[1]=190
vecdata[2]=900
vecdata[3]=737
vecdata[4]=364
templatePageNum=41
vecdata=
vecdata[0]=35
vecdata[1]=190
vecdata[2]=900
vecdata[3]=737
vecdata[4]=364
outs0.str()=
) €A@ 纆@ 孈 嘆 纕@
strbuf0=
strbuf0=
) €A@ 纆@ 孈 嘆 纕@
ttts0=
templatePageNum=41
vecdata=
vecdata[0]=35
vecdata[1]=190
vecdata[2]=900
vecdata[3]=737
vecdata[4]=364
templatePageNum=41
vecdata=
vecdata[0]=35
vecdata[1]=190
vecdata[2]=900
vecdata[3]=737
vecdata[4]=364
outs1.str()=
41
35
190
900
737
364
strbuf1=
strbuf1=
41
35
190
900
737
364
ttts1=
templatePageNum=41
vecdata=
vecdata[0]=35
vecdata[1]=190
vecdata[2]=900
vecdata[3]=737
vecdata[4]=364
templatePageNum=41
vecdata=
vecdata[0]=35
vecdata[1]=190
vecdata[2]=900
vecdata[3]=737
vecdata[4]=364
outs2.str()=
{
"value0": {
"templatePageNum": 41,
"vecdata": [
35.0,
190.0,
900.0,
737.0,
364.0
]
}
}
strbuf2=
strbuf2=
{
"value0": {
"templatePageNum": 41,
"vecdata": [
35.0,
190.0,
900.0,
737.0,
364.0
]
}
}
ttts2=
templatePageNum=41
vecdata=
vecdata[0]=35
vecdata[1]=190
vecdata[2]=900
vecdata[3]=737
vecdata[4]=364
running cereal finished!