POCO C++ 对象到 JSON 字符串序列化
POCO C++ object to JSON string serialization
我想知道如何使用 POCO C++ 库将给定 class(例如人)及其属性(例如姓名、年龄)的对象序列化为 JSON 字符串。
也许我应该使用 Poco::Dynamic 和 Poco::Dynamic::Var 创建我的模型以便使用 POCO::JSON::Stringifier?我无法想象如何做到这一点...
提前致谢!
与 Java 或 C# 不同,C++ 在 运行 时间类型信息 (RTTI) 之外没有 introspection/reflection 功能,它具有不同的重点并且仅限于多态对象。这意味着在非标准预编译器之外,您必须以某种方式告诉序列化框架您的对象是如何构建的,以及您最终希望如何将其映射到 int
、std::string
等基本数据类型。我通常会区分三种不同的方法:预编译器、内联规范、属性 转换。
预编译器:预编译器方法的一个很好的例子是Google协议缓冲区:https://developers.google.com/protocol-buffers/docs/cpptutorial。您在单独的 .proto
文件中定义您的实体,该文件使用专有编译器转换为 .c
和 .h
实体 classes。这些 classes 可以像常规 POCO 实体一样使用,并且可以使用 Protocol Buffers 进行序列化。
内联规范:Boost 序列化 (https://www.boost.org/doc/libs/1_67_0/libs/serialization/doc/index.html), s11n (www.s11n.net) and restc-cpp (https://github.com/jgaa/restc-cpp) 是在您自己的代码中为框架明确指定 POCO 结构的示例。 API 这样做可能或多或少复杂,但其背后的原理始终相同:您为 classes 提供框架 serialise
/deserialise
实现或者您注册允许框架生成它们的元数据信息。下面的示例来自 restc-cpp:
struct Post {
int userId = 0;
int id = 0;
string title;
string body;
};
BOOST_FUSION_ADAPT_STRUCT(
Post,
(int, userId)
(int, id)
(string, title)
(string, body)
)
- 属性 转换:我不想错过的最后一种序列化是显式转换为框架提供的中间数据类型。 Boost 属性 树 (https://www.boost.org/doc/libs/1_67_0/doc/html/property_tree.html) and JsonCpp (http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html) 是这种方法的很好的例子。您负责实现从您自己的类型到
ptree
的转换,Boost 可以将其序列化为您喜欢的任何格式(XML、JSON)。
根据我对 C++ 中所有三种方法的分享经验,我建议将选项 3 作为默认选项。它似乎很好地映射到 JSON 的 POCO C++ 的 Parser
和 Var
模型。一种选择是让所有实体 POCO classes 实现一个 to_var
或 from_var
函数,或者您可以将这些序列化函数保存在每个 POCO class 的不同命名空间中,这样您只需在必要时包含它们。
如果您正在处理有大量对象要序列化的项目(例如通信库中的消息),预编译器选项可能值得初始设置工作和额外的构建复杂性,但这取决于,一如既往, 关于您正在处理的具体项目。
我想知道如何使用 POCO C++ 库将给定 class(例如人)及其属性(例如姓名、年龄)的对象序列化为 JSON 字符串。
也许我应该使用 Poco::Dynamic 和 Poco::Dynamic::Var 创建我的模型以便使用 POCO::JSON::Stringifier?我无法想象如何做到这一点...
提前致谢!
与 Java 或 C# 不同,C++ 在 运行 时间类型信息 (RTTI) 之外没有 introspection/reflection 功能,它具有不同的重点并且仅限于多态对象。这意味着在非标准预编译器之外,您必须以某种方式告诉序列化框架您的对象是如何构建的,以及您最终希望如何将其映射到 int
、std::string
等基本数据类型。我通常会区分三种不同的方法:预编译器、内联规范、属性 转换。
预编译器:预编译器方法的一个很好的例子是Google协议缓冲区:https://developers.google.com/protocol-buffers/docs/cpptutorial。您在单独的
.proto
文件中定义您的实体,该文件使用专有编译器转换为.c
和.h
实体 classes。这些 classes 可以像常规 POCO 实体一样使用,并且可以使用 Protocol Buffers 进行序列化。内联规范:Boost 序列化 (https://www.boost.org/doc/libs/1_67_0/libs/serialization/doc/index.html), s11n (www.s11n.net) and restc-cpp (https://github.com/jgaa/restc-cpp) 是在您自己的代码中为框架明确指定 POCO 结构的示例。 API 这样做可能或多或少复杂,但其背后的原理始终相同:您为 classes 提供框架
serialise
/deserialise
实现或者您注册允许框架生成它们的元数据信息。下面的示例来自 restc-cpp:
struct Post {
int userId = 0;
int id = 0;
string title;
string body;
};
BOOST_FUSION_ADAPT_STRUCT(
Post,
(int, userId)
(int, id)
(string, title)
(string, body)
)
- 属性 转换:我不想错过的最后一种序列化是显式转换为框架提供的中间数据类型。 Boost 属性 树 (https://www.boost.org/doc/libs/1_67_0/doc/html/property_tree.html) and JsonCpp (http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html) 是这种方法的很好的例子。您负责实现从您自己的类型到
ptree
的转换,Boost 可以将其序列化为您喜欢的任何格式(XML、JSON)。
根据我对 C++ 中所有三种方法的分享经验,我建议将选项 3 作为默认选项。它似乎很好地映射到 JSON 的 POCO C++ 的 Parser
和 Var
模型。一种选择是让所有实体 POCO classes 实现一个 to_var
或 from_var
函数,或者您可以将这些序列化函数保存在每个 POCO class 的不同命名空间中,这样您只需在必要时包含它们。
如果您正在处理有大量对象要序列化的项目(例如通信库中的消息),预编译器选项可能值得初始设置工作和额外的构建复杂性,但这取决于,一如既往, 关于您正在处理的具体项目。