将C ++类转换为JSON
我想创build一个包含我的类的实例variables的JSONstring。
例如,
class Example { std::string string; std::map<std::string, std:string> map; std::vector<int> vector; };
会成为:
{ "string":"the-string-value", "map": { "key1":"val1", "key2":"val2" }, "vector":[1,2,3,4] }
我已经研究过几个用于创buildJSON的C ++库,它们看起来都非常复杂。 我想要类似于Javascript的JSON.stringify(object)
。 换句话说就是传递一个std :: map到它并接收一个string。 地图可以包含其他地图,vector,列表,string,数字和布尔。
什么是最好的方法来做到这一点?
谢谢你的帮助。
编辑
我已经看了下面的内容:
json精灵,jsoncpp,zoolib,JOST,CAJUN,libjson,nosjob,JsonBox,jsonme–
我理解我可以构build一个单独的JSON对象,如下面的答案,并转换为JSON我想能够存储我的东西在标准集合和转换。
编辑2
好吧,放弃序列化类的想法,因为C ++缺乏反思似乎是不可能的。
有没有一种很好的方式来转换包含std :: maps,std :: vectors,std :: lists,numbers,strings和bools的std :: map到JSON,而不必更改数据types或将数据复制到新的数据types?
谢谢。
JSON Spirit可以让你这样做:
Object addr_obj; addr_obj.push_back( Pair( "house_number", 42 ) ); addr_obj.push_back( Pair( "road", "East Street" ) ); addr_obj.push_back( Pair( "town", "Newtown" ) ); ofstream os( "address.txt" ); write( addr_obj, os, pretty_print ); os.close();
输出:
{ "house_number" : 42, "road" : "East Street", "town" : "Newtown" }
json_map_demo.cpp将是一个很好的开始,我想。
任何一个好的C ++ JSON库都应该这样做,很遗憾的是他们没有 – 除了ThorsSerializer和显然在这个问题中提到的Nosjob 。
当然,C ++没有类似Java的reflection,所以你必须明确地注释你的types:
(从ThorsSerializer文档复制)
struct MyClass { int data1; float data2; std::string data3; }; // Macro to describe persisted members generates serialization code: JsonSerializeTraits_MAKE(void, MyClass, data1, data2, data3)
这允许你例如写:
MyClass data = {56, 23.456, "Hi there"}; std::cout << ThorsAnvil::Serializer::jsonExport(data) << "\n";
在C ++中你不能做得比这更好。
你想要JSON – 如果是地图或对象? (你的例子显示一个类,但你说一个地图)。 查看地图,看看这个图书馆
对象:在C ++中没有reflection支持(除了非常有限的RTTI),所以没有“一键式”的序列化解决scheme。 任何解决scheme都需要你编写额外的,可能紧密耦合的代码到你想要序列化和反序列化的类(这取决于是否要序列化非公开数据)。
我写了一个旨在解决你的问题的图书馆。 但是,这是一个非常新的项目,不够稳定。 随意去看看,主页在这里::
https://github.com/Mizuchi/acml
在你的例子中,你必须像这样添加一行:
ACML_REGISTER(Example, ,(string)(map)(vector));
为了告诉图书馆你想转储的成员。 由于C ++没有反映。 你必须给出一个方法来访问该成员,或者使用公共成员级别或使用朋友类。
后来你只需要这样做:
string result = acml :: json :: dumps(any_object);
会成为::
{ "string": "the-string-value", "map": { "key1": "val1", "key2": "val2" }, "vector": { "type": "std::vector", "size": "4", "0": "1", "1": "2", "2": "3", "3": "4" } }
如您所见,JSON数组尚未实现。 现在一切都变成了弦乐。
你看过麦片( http://uscilab.github.io/cereal/ )吗? 它具有JSON存档,用于使用C ++序列化/从JSON。
一个最小的开销(谷物)的例子可以在这里findSO: https : //stackoverflow.com/a/22587527/255635
我已经写了一个可以完成这个工作的实验库,但是它需要对类结构和层次结构的外部描述。 它使用GCCXML构build一个xml字典,用于序列化反序列化:
http://code.google.com/p/cjson/
这是一个实验项目,它可以处理基本types(int,float double),基本types的指针,类,inheritance的成员等…它实现基本的std :: vector和std :: map序列化,也std :: string实例。
请参阅此处的实施细节
这个 python脚本为每个json属性生成一个成员的c ++ pod类
你需要完全相反的东西,但是生成一个既能加载又能保存的映射类是微不足道的
生成的代码依赖于外部的jsonparsing器库
如果问题仍然存在,请查看json_dto库,这是一个用于在JSON表示和c ++结构之间转换数据的小型头标助手。
例如有以下结构:
struct message_source_t { // Worker thread. std::int32_t m_thread_id; // Sender. std::string m_subsystem; }; struct message_t { // Who sent a message. message_source_t m_from; // When the message was sent (unixtime). std::tm m_when; // Message text. std::string m_text; };
在json_dto的帮助下,您可以创build以下JSON:
{ "from" : { "thread_id" : 4242, "sybsystem" : "json_dto" }, "when" : "2016.09.28 19:55:00", "text" : "Hello world!" }
给了这样的JSONstring,你可以将其转换为结构。