当需要将内存中的对象通过网络传输(或者以文件的方式存储)的时候,需要用到序列化。
对于基于网络的远程调(RPC)用来说,通过序列化将自定义对象通过网络传输能极大地简化系统的数据,也很容易实现 corba, wamp等功能。
通过网络传输对象时,可以使用JSON,ProtoBuf 和 MsgPack,下面简要介绍一下msgpack-c的使用:
msgpack example:
#include <msgpack.hpp>
#include <vector>
#include <string>
#include <iostream>
int main(void)
{
// serializes this object.
std::vector<std::string> vec;
vec.push_back("Hello");
vec.push_back("MessagePack");
// serialize it into simple buffer.
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, vec);
// 序列化之后再通过tcp/ip发送出去(wamp原型):
// boost::asio::write(socket, boost::asio::buffer(sbuf.data(), sbuf.size()));
// 然后再远端再 deserialize it.
msgpack::object_handle oh =
msgpack::unpack(sbuf.data(), sbuf.size());
// print the deserialized object.
msgpack::object obj = oh.get();
std::cout << obj << std::endl; //=> ["Hello", "MessagePack"]
// convert it into statically typed object.
std::vector<std::string> rvec;
obj.convert(rvec);
}
编译,运行:
$ g++ -Ipath_to_msgpack/include hello.cc -o hello
$ ./hello
["Hello", "MessagePack"]
对于自定义类型,希望通过 msgpack pack&unpack,可以通过如下模板实现(non-intrusive approach):
struct MyClass
{
int a;
double int b;
std::vector<double> c;
}
// used for pack
template <>
struct object_with_zone<MyClass>
{
void operator()(msgpack::object::with_zone& o, MyClass const& v) const {
o.type = type::ARRAY;
o.via.array.size = 3;
o.via.array.ptr = static_cast<msgpack::object*>(
o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size));
o.via.array.ptr[0] = msgpack::object(v.a, o.zone);
o.via.array.ptr[1] = msgpack::object(v.b, o.zone);
o.via.array.ptr[2] = msgpack::object(v.c, o.zone);
}
};
// used for unpack
template <>
struct convert<MyClass>
{
msgpack::object const& operator()(msgpack::object const& o, MyClass& v) const
{
if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
if (o.via.array.size != 3) throw msgpack::type_error();
v.a = o.via.array.ptr[0].as<int>();
v.b = o.via.array.ptr[1].as<double>();
v.c = o.via.array.ptr[2].as<std::vector<double>>();
return o;
}
};
reference link:
https://github.com/msgpack/msgpack-c/wiki/v1_1_cpp_adaptor
https://github.com/msgpack/msgpack-c/blob/master/example/cpp11/container.cpp