msgpack的object_with_zone是做什么的?

时间:2017-07-28 06:06:07

标签: c++ msgpack

msgpack_c编写自定义序列化程序时,还需要实现object_with_zone

如何实现这一目标的文档非常稀疏(https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor)。

在什么情况下调用此方法?

1 个答案:

答案 0 :(得分:1)

您可以从C ++类型创建msgpack::object。 见https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#conversion

当您使用msgpack::object区域调用msgpack::object(mc, z);构造函数时,会在内部调用object_with_zone<T>::operator()

如果您不想从C ++类型创建msgpack::object,则无需定义object_with_zone专业化。包装,解包和转换为msgpack::object的C ++类型并不需要它。

以下是一个例子:

#include <iostream>
#include <msgpack.hpp>

class my_class {
public:
    my_class(std::string const& name, int age):name_(name), age_(age) {}

    std::string const& get_name() const { return name_; }
    int get_age() const { return age_; }

private:
    std::string name_;
    int age_;
};

// User defined class template specialization
namespace msgpack {
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
namespace adaptor {

template <>
struct object_with_zone<my_class> {
    void operator()(msgpack::object::with_zone& o, my_class const& v) const {
        std::cout << "object_with_zone<my_class> is called" << std::endl;
        o.type = type::ARRAY;
        o.via.array.size = 2;
        o.via.array.ptr = static_cast<msgpack::object*>(
            o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
        o.via.array.ptr[0] = msgpack::object(v.get_name(), o.zone);
        o.via.array.ptr[1] = msgpack::object(v.get_age(), o.zone);
    }
};

} // namespace adaptor
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
} // namespace msgpack

int main() {
    my_class mc("John", 42);
    msgpack::zone z;
    auto obj = msgpack::object(mc, z);
    std::cout << obj << std::endl;
}

输出:

object_with_zone<my_class> is called
["John", 42]

正在运行演示:https://wandbox.org/permlink/dNmZX1FpUL3w8D5m

<强>更新

其他问题。 Why would i want to use the zone ?

答案:

解包MessagePack格式的字节流时,内部使用区域。你得到msgpack::object_handlemsgpack::object_handle有一个区域和一个msgpack::object。请参阅https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#what-is-msgpackobject

使用msgpack::zone的原因是为了提高性能。如果msgpack::objectSTRBINEXT,则msgpack::object需要动态分配内存。 msgpack::object可以自己处理内存,但效率很低。如果msgpack::object分配内存,msgpack::object的析构函数需要释放内存。 msgpack::object是一个复合数据结构。这意味着析构函数不能内联。

msgpack-c的目标之一是高效解包。所以msgpack-c使用msgpack::zone

正在解开故事。从C ++类型创建msgpack::zone时也会使用msgpack::object。我不确定用户想要做什么,取决于用户。