我正在尝试使用 msgpack。我有一个接收器和一个发送器。发送者是一个 C++ 客户端,接收者是一个 erlang 服务器。
当我有一个 erlang 服务器和一个 erlang 客户端时,Msgpack 非常棒。我曾经发送和接收数据类型,如列表、元组、映射、二进制、erlang 和 msgpack:pack() 和 msgpack:unpack() 完全没问题。但是当我开始将我的发件人更改为 C++ 客户端时,我开始思考这个问题:
msgpack 可以打包用户定义的数据结构,如类和结构。 ?如果我有一个复杂的结构并使用 msgpack:pack() 和在接收端打包,当我使用 msgpack:unpack() 时,我可以告诉它解码为我感兴趣的特定数据类型吗?可能是一个元组?
谢谢。 !
最佳答案
是的,你可以做到。 msgpack-c 支持 C 和 C++。我写了关于 msgpack-c 的 C++ 部分。 msgpack-c 可以打包任何具有适配器的类型。这是预先支持的 C++ 类型 https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor 的列表
您还可以为用户定义的类型编写适配器。最简单的方法是使用 MSGPACK_DEFINE(映射到 ARRAY)或 MSGPACK_DEFINE_MAP(映射到 MAP)。
只要类型具有适配器,您就可以组合和组合任何类型。如果在 your_type
中写入 MSGPACK_DEFINE ,则可以打包 std::vector<std::map<std::string, your_type> >
。
当您解压 MessageePack 格式的数据时,您会得到 msgpack::object_handle
。见 https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_unpacker 。
然后你可以从 msgpack::object
得到 msgpack::object_handle
。最后,您可以使用 msgpack::object
成员函数将 as()
转换为任何具有适配器的类型。
见 https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#conversion
这是一个示例代码:
#include <iostream>
#include <sstream>
#include <cassert>
#include <msgpack.hpp>
struct your_type {
int a;
int b;
MSGPACK_DEFINE(a, b);
};
bool operator==(your_type const& lhs, your_type const& rhs) {
return lhs.a == rhs.a && lhs.b == rhs.b;
}
int main() {
// packing
std::stringstream ss;
std::vector<std::map<std::string, your_type>> v
{
{
{ "key1", {1,2} },
{ "key2", {3,4} }
},
{
{"key3", {5, 6} }
}
};
msgpack::pack(ss, v);
// unpacking
msgpack::object_handle oh = msgpack::unpack(ss.str().data(), ss.str().size());
msgpack::object const& obj = oh.get();
std::cout << "object: " << obj << std::endl;
// converting
auto v2 = obj.as<std::vector<std::map<std::string, your_type>>>();
assert(v == v2);
}
并且可以在Wandbox的在线编译环境中运行、修改:
http://melpon.org/wandbox/permlink/M229kOVY6ys83pwb
关于c++ - 使用 msgpack 对用户定义的结构进行编码。,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40896477/