msgpack 的 object_with_zone 有什么作用?
what does msgpack's object_with_zone do?
为 msgpack_c
编写自定义序列化程序时,还需要实现 object_with_zone
.
关于如何实现它的文档非常少 (https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor)。
什么情况下调用这个方法?
您可以从 C++ 类型创建 msgpack::object
。
参见 https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#conversion
当您使用 msgpack::object(mc, z);
等区域调用 msgpack::object
构造函数时,会在内部调用 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
已更新
补充问题。
答案:
当您解压 MessagePack 格式的字节流时,内部会使用一个区域。你得到 msgpack::object_handle
。 msgpack::object_handle
有一个区域和一个 msgpack::object
。参见 https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#what-is-msgpackobject。
之所以使用msgpack::zone
是为了性能。如果msgpack::object
是STR
、BIN
或EXT
,则msgpack::object
需要动态分配内存。 msgpack::object
本身可以拥有内存句柄,但效率低下。 msgpack::object
的析构函数需要释放内存,如果msgpack::object
分配内存。 msgpack::object
是复合数据结构。这意味着不能内联析构函数。
msgpack-c 的目标之一是高效解包。所以 msgpack-c 使用 msgpack::zone
.
开箱故事。当从 C++ 类型创建 msgpack::object
时,也会使用 msgpack::zone
。我不确定用户什么时候想做,这取决于用户。
为 msgpack_c
编写自定义序列化程序时,还需要实现 object_with_zone
.
关于如何实现它的文档非常少 (https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor)。
什么情况下调用这个方法?
您可以从 C++ 类型创建 msgpack::object
。
参见 https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#conversion
当您使用 msgpack::object(mc, z);
等区域调用 msgpack::object
构造函数时,会在内部调用 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
已更新
补充问题。
答案:
当您解压 MessagePack 格式的字节流时,内部会使用一个区域。你得到 msgpack::object_handle
。 msgpack::object_handle
有一个区域和一个 msgpack::object
。参见 https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_object#what-is-msgpackobject。
之所以使用msgpack::zone
是为了性能。如果msgpack::object
是STR
、BIN
或EXT
,则msgpack::object
需要动态分配内存。 msgpack::object
本身可以拥有内存句柄,但效率低下。 msgpack::object
的析构函数需要释放内存,如果msgpack::object
分配内存。 msgpack::object
是复合数据结构。这意味着不能内联析构函数。
msgpack-c 的目标之一是高效解包。所以 msgpack-c 使用 msgpack::zone
.
开箱故事。当从 C++ 类型创建 msgpack::object
时,也会使用 msgpack::zone
。我不确定用户什么时候想做,这取决于用户。