首页 > 解决方案 > 谷物 - 无法反序列化 json 字符串 - 未处理的异常

问题描述

这是我的 json 字符串

{
    "connectionString" : "MyConnectionString",
    "value" :"MyVal"
}

这是我的课

        struct Settings
        {
            std::string connectionString;
            std::string value;

            template<class Archive>
            void serialize(Archive& ar)
            {
                    ar(CEREAL_NVP(connectionString),
                    CEREAL_NVP(value)
                );
            }
        };

这就是我正在做的事情:

            std::ifstream ifs("Settings.json");
            std::string content((std::istreambuf_iterator<char>(ifs)),(std::istreambuf_iterator<char>())); // Yes this is valid - The content gets populated
            
            Settings settings;
            {
                cereal::JSONInputArchive archive_in(ifs);
                archive_in(settings); //<<-----Exception here - Unhandled exception
            }

只有当我的 json 字符串是这个(即)如果所有 json 字符串都是另一个键的对象时,上述解决方案才有效。

{
    "SomeThing" :{
                "connectionString" : "MyConnectionString",
                "value" :"MyVal"
       }
}

我的问题是如何使我的实际 json 字符串工作(而不将其包装在对象中)?我目前在 json 文件中有这个

{
    "connectionString" : "MyConnectionString",
    "value" :"MyVal"
}

我想知道将其反序列化为对象的最佳方法?

标签: c++cereal

解决方案


期望外部对象的代码通过默认的 JSON“序言”和“尾声”行为放在那里:

https://github.com/USCiLab/cereal/blob/10d9a29c225fe9a843d043bfe9f13c5f958844dc/include/cereal/archives/json.hpp#L837

文档

为这些函数提供了对活动存档的引用和对正在序列化的类型的常量引用。prologue 和 epilogue 的仔细专业化允许档案执行特殊行为,而无需重新实现类型的序列化功能。这让我们可以使类型支持相当通用。例如,谷物::XMLOutputArchive (<cereal/archives/xml.hpp>) 使用这些函数来开始和结束其内存树中的节点。

如果您在代码中为您的类型添加一个不执行任何操作的重载:

void epilogue(cereal::JSONInputArchive&, const Settings&) { }
void prologue(cereal::JSONInputArchive&, const Settings&) { }

它不会尝试解析外部对象


推荐阅读