news 2026/11/2 1:13:24

C/C++ JSON ORM

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C/C++ JSON ORM
structs
#include "json_struct.h" #include <vector> JS_ENUM(Error, None, InvalidRange, IllegalParam, Nullptr, OverLimitLen) JS_ENUM_DECLARE_STRING_PARSER(Error) // 搜索匹配区域 struct RangeContent { size_t start; size_t end; std::string content; JS_OBJ(start, end, content); }; struct Result { Error errorCode; std::vector<RangeContent> contents; JS_OBJECT(JS_MEMBER(errorCode), JS_MEMBER(contents)); }; void test() { // 序列 Result result; std::string json = JS::serializeStruct(result, JS::SerializerOptions(JS::SerializerOptions::Compact)); // 反序列 Result resultNew; JS::ParseContext parseContext(json); auto error = parseContext.parseTo(resultNew); if (JS::Error::NoError != error) { std::string errorStr = parseContext.makeErrorString(); fprintf(stderr, "Error parsing struct %s\n", errorStr.c_str()); } }
jsonifier
// // Created by ws on 2024/8/29. // #include <vector> #include "jsonifier/String.hpp" #include "jsonifier/Tuple.hpp" #include "jsonifier/Index.hpp" #include "jsonifier/Serializer.hpp" #include "jsonifier/JsonifierCore.hpp" namespace TestNS { struct fixed_object_t { std::vector<int32_t> int_array; std::vector<float> float_array; std::vector<double> double_array; }; struct fixed_name_object_t { jsonifier::string name0{}; jsonifier::string name1{}; jsonifier::string name2{}; jsonifier::string name3{}; jsonifier::string name4{}; }; struct nested_object_t { std::vector<std::array<double, 3>> v3s{}; jsonifier::string id{}; }; struct another_object_t { jsonifier::string string{}; jsonifier::string another_string{}; bool boolean{}; nested_object_t nested_object{}; }; struct obj_t { fixed_object_t fixed_object{}; fixed_name_object_t fixed_name_object{}; another_object_t another_object{}; std::vector<jsonifier::string> string_array{}; jsonifier::string string{}; double Number{}; bool boolean{}; bool another_bool{}; }; } namespace jsonifier { template<> struct core<TestNS::fixed_object_t> { using value_type = TestNS::fixed_object_t; static constexpr auto parseValue = createValue("int_array", &value_type::int_array, "float_array", &value_type::float_array, "double_array", &value_type::double_array); }; template<> struct core<TestNS::fixed_name_object_t> { using value_type = TestNS::fixed_name_object_t; static constexpr auto parseValue = createValue("name0", &value_type::name0, "name1", &value_type::name1, "name2", &value_type::name2, "name3", &value_type::name3, "name4", &value_type::name4); }; template<> struct core<TestNS::nested_object_t> { using value_type = TestNS::nested_object_t; static constexpr auto parseValue = createValue("v3s", &value_type::v3s, "id", &value_type::id); }; template<> struct core<TestNS::another_object_t> { using value_type = TestNS::another_object_t; static constexpr auto parseValue = createValue("string", &value_type::string, "another_string", &value_type::another_string, "boolean", &value_type::boolean, "nested_object", &value_type::nested_object); }; template<> struct core<TestNS::obj_t> { using value_type = TestNS::obj_t; static constexpr auto parseValue = createValue("fixed_object", &value_type::fixed_object, "fixed_name_object", &value_type::fixed_name_object, "another_object", &value_type::another_object, "string_array", &value_type::string_array, "string", &value_type::string, "Number", &value_type::Number, "boolean", &value_type::boolean, "another_bool", &value_type::another_bool); }; } int main() { jsonifier::jsonifier_core myParser{}; // jsonifier::string buffer{ json_data }; TestNS::obj_t obj{}; obj.string = "hello world"; obj.Number = 12.33242; // Serialize and obtain the serialized JSON string directly. jsonifier::serialize_options options; options.prettify = true; // Enable prettifying options.indentSize = 2; // Set custom prettifyJson options if needed. auto stringToWrite = myParser.serializeJson(obj); std::cout << stringToWrite << std::endl; // Deserialize TestNS::obj_t newObj{}; std::string dataToParse = "{\"Number\":12.33242,\"another_object\":{\"another_string\":\"\",\"boolean\":false,\"nested_object\":{\"id\":\"\",\"v3s\":[]},\"string\":\"\"},\"another_bool\":false,\"boolean\":false,\"fixed_object\":{\"double_array\":[],\"float_array\":[],\"int_array\":[]},\"fixed_name_object\":{\"name0\":\"\",\"name1\":\"\",\"name2\":\"\",\"name3\":\"\",\"name4\":\"\"},\"string_array\":[],\"string\":\"hello world\"}"; auto result = myParser.parseJson<jsonifier::parse_options{ .validateJson = true, .minified = false }>(newObj, dataToParse); std::cout << newObj.string << " " << newObj.Number << std::endl; }

{"Number":12.33242,"another_object":{"another_string":"","boolean":false,"nested_object":{"id":"","v3s":[]},"string":""}
,"another_bool":false,"boolean":false,"fixed_object":{"double_array":[],"float_array":[],"int_array":[]},"fixed_name_obj
ect":{"name0":"","name1":"","name2":"","name3":"","name4":""},"string_array":[],"string":"hello world"}
hello world 12.3324

nlohmann
#include "nlohmann/json.hpp" using json = nlohmann::json; template <typename T> bool json2obj(const char* pcJson, T &out, std::string *err = nullptr) { try { out = json::parse(pcJson); return true; } catch (const json::exception &e) { if (err != nullptr) *err = e.what(); return false; } } enum class Type { MAN = 4, WONMAN, NONE, }; NLOHMANN_JSON_SERIALIZE_ENUM(Type, {{Type::WONMAN, "WONMAN"}, {Type::MAN, "MAN"}, {Type::NONE, "NONE"}, }); struct Value{ std::optional<bool> isBeyond;//是否超出 std::optional<Type> type;//类型 }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Value, isBeyond, type) /* 自定义Key-Value映射解析 inline void to_json(nlohmann::json& j, const Value& t) { j["dataType"] = t.type; j["over"] = t.isBeyond; } inline void from_json(const nlohmann::json& j, Value& t) { t.type = j["dataType"]; t.isBeyond = j["over"]; }*/ // json解析 int main() { Value value; nlohmann::json json_data = value; value = json_data; // Value value = nlohmann::json::parse(event->argument()); // nlohmann::json json_data = nlohmann::json::parse(json_string); // nlohmann::json json_data = json_string; // std::string json_string = json_data.dump(); }
draw_json_link
#include <daw/daw_span.h> #include <daw/daw_tuple_forward.h> #include <daw/json/daw_json_link.h> #include <daw/json/daw_json_schema.h> #include <cassert> #include <cstdio> #include <iostream> #include <map> #include <string> #include <tuple> #include <variant> struct Bar { int a = 9; int type = 0; }; struct Umm { double a = 12.1; int type = 1; }; struct Foo { int a = 1; double b = 2.2; std::string c = "3"; std::vector<int> d = { 1, 2, 3, 4 }; Bar e; std::map<std::string, Bar> f; std::map<int, float> g; std::variant<int, std::string, bool> h; std::variant<int, std::string, bool, Bar, Umm> i; std::optional<int> j; std::unique_ptr<int[]> l = std::unique_ptr<int[]>( new int[0] ); int k; std::tuple<int, double> m{ 99, 98.8 }; std::variant<Bar, Umm> n{ Umm{} }; std::tuple<double, std::string, int, std::variant<Bar, Umm>> o{ 1.1, "2", 1, Umm{} }; }; struct FooBoo { int a = 1; double b = 2.2; std::string_view c = "3"; Bar e{ }; std::variant<int, std::string_view, bool> h{ 5 }; std::variant<int, std::string_view, bool, Bar, Umm> i{ bool{} }; std::optional<int> j{ }; int k{ }; std::tuple<int, double> m{ 99, 98.8 }; std::variant<Bar, Umm> n{ Umm{} }; std::tuple<double, std::string_view, int, std::variant<Bar, Umm>> o{ 1.1, "2", 1, Umm{} }; }; template<typename... Ts> struct IdentitySwitcher { constexpr std::size_t operator( )( std::size_t n ) const { assert( n < sizeof...( Ts ) ); return n; } inline std::size_t operator( )( Foo const &f ) const { return f.i.index( ); } inline std::size_t operator( )( FooBoo const &f ) const { return f.i.index( ); } }; template<typename T> struct UniquePtrArrayCtor { constexpr std::unique_ptr<T[]> operator( )( ) const { return { }; } template<typename Iterator> inline std::unique_ptr<T[]> operator( )( Iterator first, Iterator last, std::size_t sz ) const { auto result = std::unique_ptr<T[]>( new T[static_cast<std::size_t>( sz )] ); auto out_last = std::copy( first, last, result.get( ) ); (void)out_last; auto const elements_copied = out_last - result.get( ); (void)elements_copied; assert( elements_copied >= 0 ); assert( static_cast<std::size_t>( elements_copied ) == sz ); return result; } }; namespace daw::json { inline constexpr char const mem_a[] = "a"; inline constexpr char const mem_b[] = "b"; inline constexpr char const mem_c[] = "c"; inline constexpr char const mem_d[] = "d"; inline constexpr char const mem_e[] = "e"; inline constexpr char const mem_f[] = "f"; inline constexpr char const mem_g[] = "g"; inline constexpr char const gkey[] = "k"; inline constexpr char const gvalue[] = "v"; inline constexpr char const mem_h[] = "h"; inline constexpr char const mem_type[] = "type"; inline constexpr char const mem_i[] = "i"; inline constexpr char const mem_j[] = "j"; inline constexpr char const mem_k[] = "k"; inline constexpr char const mem_l[] = "l"; inline constexpr char const mem_m[] = "m"; inline constexpr char const mem_n[] = "n"; inline constexpr char const mem_o[] = "o"; template<> struct json_data_contract<Bar> { using type = json_tuple_member_list<int, int>; static constexpr auto to_json_data( Bar const &b ) { return std::forward_as_tuple( b.a, b.type ); } }; template<> struct json_data_contract<Umm> { using type = json_tuple_member_list<double, int>; static constexpr auto to_json_data( Umm const &b ) { return std::forward_as_tuple( b.a, b.type ); } }; template<> struct json_data_contract<Foo> { using force_aggregate_construction = void; using type = json_member_list< json_link<mem_a, int>, json_link<mem_b, double>, json_link<mem_c, std::string>, json_link<mem_d, std::vector<int>>, json_link<mem_e, Bar>, json_link<mem_f, std::map<std::string, Bar>>, json_key_value_array<mem_g, std::map<int, float>, json_link<gvalue, float>, json_link<gkey, int>>, json_variant<mem_h, std::variant<int, std::string, bool>>, json_tagged_variant<mem_i, std::variant<int, std::string, bool, Bar, Umm>, json_link<mem_type, std::size_t>, IdentitySwitcher<int, std::string, bool, Bar, Umm>>, json_link<mem_j, std::optional<int>>, json_sized_array<mem_l, int, json_link<mem_k, int>, std::unique_ptr<int[]>, UniquePtrArrayCtor<int>>, json_link<mem_k, int>, json_tuple<mem_m, std::tuple<int, double>>, json_intrusive_variant<mem_n, std::variant<Bar, Umm>, json_tuple_member<1, std::size_t>, IdentitySwitcher<Bar, Umm>>, json_tuple<mem_o, std::tuple<double, std::string, int, std::variant<Bar, Umm>>, json_tuple_types_list< double, std::string, int, json_tagged_variant_no_name< std::variant<Bar, Umm>, json_tuple_member<2, std::size_t>, IdentitySwitcher<Bar, Umm>>>>>; static inline auto to_json_data( Foo const &v ) { return daw::forward_nonrvalue_as_tuple( v.a, v.b, v.c, v.d, v.e, v.f, v.g, v.h, v.i, v.j, daw::span( v.l.get( ), static_cast<std::size_t>( v.k ) ), v.k, v.m, v.n, v.o ); } }; template<> struct json_data_contract<FooBoo> { using force_aggregate_construction = void; using type = json_member_list< json_link<mem_a, int>, json_link<mem_b, double>, json_link<mem_c, std::string_view>, json_link<mem_e, Bar>, json_variant<mem_h, std::variant<int, std::string_view, bool>>, json_tagged_variant< mem_i, std::variant<int, std::string_view, bool, Bar, Umm>, json_link<mem_type, std::size_t>, IdentitySwitcher<int, std::string_view, bool, Bar, Umm>>, json_link<mem_j, std::optional<int>>, json_link<mem_k, int>, json_tuple<mem_m, std::tuple<int, double>>, json_intrusive_variant<mem_n, std::variant<Bar, Umm>, json_tuple_member<1, std::size_t>, IdentitySwitcher<Bar, Umm>>, json_tuple< mem_o, std::tuple<double, std::string_view, int, std::variant<Bar, Umm>>, json_tuple_types_list< double, std::string_view, int, json_tagged_variant_no_name<std::variant<Bar, Umm>, json_tuple_member<2, std::size_t>, IdentitySwitcher<Bar, Umm>>>>>; static inline auto to_json_data( FooBoo const &v ) { return daw::forward_nonrvalue_as_tuple( v.a, v.b, v.c, v.e, v.h, v.i, v.j, v.k, v.m, v.n, v.o ); } }; } // namespace daw::json int main( ) { using namespace daw::json::options; std::string result = daw::json::to_json_schema<Foo>( "", "Foo", output_flags<SerializationFormat::Pretty> ); puts( result.c_str( ) ); puts( "----\n" ); std::string json_str1 = daw::json::to_json( Foo{ }, output_flags<SerializationFormat::Pretty> ); puts( json_str1.c_str( ) ); puts( "\n----\n\n" ); auto foo2 = daw::json::from_json<Foo>( json_str1 ); (void)foo2; std::string json_str2 = daw::json::to_json( FooBoo{ } ); puts( json_str2.c_str( ) ); auto fooboo = daw::json::from_json<FooBoo>( json_str2 ); std::cout << "\n----------------------------------------\n" << daw::json::to_json( fooboo ) << '\n'; }
参考

GitHub - RealTimeChris/Jsonifier: A few classes for parsing and serializing objects from/into JSON, in C++ - very rapidly.

GitHub - jorgen/json_struct: json_struct is a single header only C++ library for parsing JSON directly to C++ structs and vice versa

GitHub - nlohmann/json: JSON for Modern C++

GitHub - beached/daw_json_link: Fast, convenient JSON serialization and parsing in C++

GitHub - stephenberry/json_performance: Performance profiling of JSON libraries


创作不易,小小的支持一下吧!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/2 1:09:00

工业级SPI硬件隔离设计:MAX14431BAEE+与PIC18F86K90实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/2 1:07:46

黑客+AI组合拳下的西门子PLC:工控安全实战拆解与防御指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/2 1:07:03

正激变换器变压器设计全解析:从磁复位到绕制工艺

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/2 1:06:47

dsPIC33FJ256GP710A与MAX14431BAEE+的隔离SPI通信设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/2 1:06:33

PLFM_RADAR:模块化雷达信号处理与目标探测平台设计实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华