提升C++操作Json的开发效率

news2024/11/27 23:52:21

一、背景

在C++项目开发中,不同的服务之间会定义通讯接口,接口格式定义中的通讯数据往往是json格式的。为了快速开发,我的需求如下:

1.定义好通讯接口后,就定义好了交互的json内容格式。我希望有工具可以一键将json内容转换成C++结构体;

2.服务交互过程中,我希望结构体数据和json内容可以相互转换,并且不需要写两者之间的转换代码。请注意:重点是不需要写两者之间的转换代码

二、解决方案

先说需求2,我在网上找到一个开源库,可以满足此需求,开源库介绍地址:

json与C++结构体互相转换_c++ 结构体转json_xyz347的博客-CSDN博客

gitee地址:xpack: 用于C++结构体和json/xml/bson/mysql的互相转换

简单介绍一下这个库的作用及用法:如下图所示,在结构体中增加XPACK宏定义,就可以轻松完成json字符串与结构体之间相互转换了,节省了大量的编写转换代码的时间。

也许有人会说,上图所示的结构体就2个变量,写转换代码几行就搞定了。

如果json的内容如下呢?写转换代码的工作量大不大呢?

{
    "status": 0,
    "message": "message",
    "data": {
        "search_data": [{
                "elements": [{
                        "rating": 0,
                        "name": "奈良市",
                        "url": "/scenic/3/10052/",
                        "wish_to_go_count": 328,
                        "name_orig": "奈良市",
                        "visited_count": 1958,
                        "comments_count": 0,
                        "location": {
                            "lat": 34.685087,
                            "lng": 135.805
                        },
                        "has_experience": false,
                        "rating_users": 0,
                        "name_zh": "奈良市",
                        "name_en": "Nara",
                        "type": 3,
                        "id": 10052,
                        "has_route_maps": false,
                        "icon": "http://media.breadtrip.com/images/icons/2/city.png"
                    },
                    {
                        "rating": 0,
                        "name": "小樽市",
                        "url": "/scenic/3/26772/",
                        "wish_to_go_count": 266,
                        "name_orig": "小樽市",
                        "visited_count": 954,
                        "comments_count": 0,
                        "location": {
                            "lat": 43.190717,
                            "lng": 140.994662
                        },
                        "has_experience": false,
                        "rating_users": 0,
                        "name_zh": "小樽市",
                        "name_en": "Otaru",
                        "type": 3,
                        "id": 26772,
                        "has_route_maps": false,
                        "icon": "http://media.breadtrip.com/images/icons/2/city.png"
                    },
                    {
                        "rating": 0,
                        "name": "挪威",
                        "url": "/scenic/1/3258/",
                        "wish_to_go_count": 788,
                        "name_orig": "挪威",
                        "visited_count": 850,
                        "comments_count": 0,
                        "location": {
                            "lat": 60.472024,
                            "lng": 8.468946
                        },
                        "has_experience": false,
                        "icon": "http://media.breadtrip.com/images/icons/2/country.png",
                        "type": 1,
                        "id": 26773,
                        "has_route_maps": false,
                        "rating_users": 0
                    }
                ],
                "type": "destination",
                "title": "国外热门目的地"
            },
            {
                "elements": [{
                        "rating": 0,
                        "name": "台湾",
                        "url": "/scenic/1/3660/",
                        "wish_to_go_count": 37947,
                        "name_orig": "台湾",
                        "visited_count": 15729,
                        "comments_count": 0,
                        "location": {
                            "lat": 23.69781,
                            "lng": 120.960515
                        },
                        "has_experience": false,
                        "icon": "http://media.breadtrip.com/images/icons/2/country.png",
                        "type": 1,
                        "id": 45012,
                        "has_route_maps": false,
                        "rating_users": 0
                    },
                    {
                        "rating": 0,
                        "name": "香港",
                        "url": "/scenic/1/3814/",
                        "wish_to_go_count": 23495,
                        "name_orig": "香港",
                        "visited_count": 31249,
                        "comments_count": 0,
                        "location": {
                            "lat": 22.396428,
                            "lng": 114.109497
                        },
                        "has_experience": false,
                        "icon": "http://media.breadtrip.com/images/icons/2/country.png",
                        "type": 1,
                        "id": 55012,
                        "has_route_maps": true,
                        "rating_users": 0
                    },
                    {
                        "rating": 0,
                        "name": "厦门",
                        "url": "/scenic/3/65012/",
                        "wish_to_go_count": 29887,
                        "name_orig": "厦门",
                        "visited_count": 26077,
                        "comments_count": 0,
                        "location": {
                            "lat": 24.477188,
                            "lng": 118.094398
                        },
                        "has_experience": false,
                        "rating_users": 0,
                        "name_zh": "厦门",
                        "name_en": "Xiamen",
                        "type": 3,
                        "id": 65012,
                        "has_route_maps": false,
                        "icon": "http://media.breadtrip.com/images/icons/2/city.png"
                    }
                ],
                "type": "destination",
                "title": "国内热门目的地"
            }
        ],
        "date_time": "2017-09-11 10:52:27.811321",
        "elements": [{
                "type": 1,
                "data": [{
                        "platform": "android",
                        "image_url": "http://photos.breadtrip.com/covers_2017_09_05_d5b225291045767fcfa0508f3d96ae26.jpg?imageView/2/w/960/",
                        "html_url": "http://www.iqiyi.com/v_19rr8w7drg.html?dummy=&wx_uid2=wxidoG0a9jsIGfq1jln1HtWebMCOKKSQ"
                    },
                    {
                        "platform": "android",
                        "image_url": "http://photos.breadtrip.com/covers_2014_12_25_ed43331bac65ee0752f7e56116993b2c.jpg?imageView2/2/w/750/format/jpg/interlace/1/",
                        "html_url": "http://web.breadtrip.com/mobile/destination/topic/2387718817/"
                    },
                    {
                        "platform": "android",
                        "image_url": "http://photos.breadtrip.com/covers_2014_10_29_46217a91ace672787ed1fec4c2011b52.png?imageView2/2/w/750/format/jpg/interlace/1/",
                        "html_url": "http://web.breadtrip.com/mobile/destination/topic/2387718790/"
                    }

                ],
                "desc": "广告banner"
            },
            {
                "type": 11,
                "data": [{
                    "title": "每日精选故事"
                }],
                "desc": ""
            }

        ]
    }
}

 使用xpack开源库之后,只需要如下定义结构体即可,转换代码不需要你写!!

struct Location {
    int lat;
    int lng;
    XPACK(O(lat, lng)); // 添加宏定义XPACK在结构体定义结尾
};

struct Elements2 {
    int comments_count;
    bool has_experience;
    bool has_route_maps;
    std::string icon;
    int id;
    Location location;
    std::string name;
    std::string name_en;
    std::string name_orig;
    std::string name_zh;
    int rating;
    int rating_users;
    int type;
    std::string url;
    int visited_count;
    int wish_to_go_count;
    XPACK(O(comments_count, has_experience, has_route_maps, icon, id, location, name, name_en, name_orig, name_zh, rating, rating_users, type, url, visited_count, wish_to_go_count)); // 添加宏定义XPACK在结构体定义结尾
};

struct Search_data {
    std::vector<Elements2> elements;
    std::string title;
    std::string type;
    XPACK(O(elements, title, type)); // 添加宏定义XPACK在结构体定义结尾
};

struct Data2 {
    std::string html_url;
    std::string image_url;
    std::string platform;
    XPACK(O(html_url, image_url, platform)); // 添加宏定义XPACK在结构体定义结尾
};

struct Elements {
    std::vector<Data2> data;
    std::string desc;
    int type;
    XPACK(O(data, desc, type)); // 添加宏定义XPACK在结构体定义结尾
};

struct Data {
    std::string date_time;
    std::vector<Elements> elements;
    std::vector<Search_data> search_data;
    XPACK(O(date_time, elements, search_data)); // 添加宏定义XPACK在结构体定义结尾
};

struct Ticket {
    Data data;
    std::string message;
    int status;
    XPACK(O(data, message, status)); // 添加宏定义XPACK在结构体定义结尾
};

到此为止,我的需求2已经完美解决了。再说需求1,请看上面那段复杂的json示例,要根据这个json格式定义结构体,工作量大不大?有没有工具可以将上面的json转换成结构体定义?我在网上找了很久,找到一个勉强能用的,网址是:Instantly parse JSON in any language | quicktype

转换效果如下:

这个在线网站转换出来的结构体定义,我还需要手动添加XPACK宏才能配合xpack开源库

使用。为了追求极致的开发效率,我使用Qt5手撸了一个转换工具,工具使用效果如下:

 如上图所示,只需要将json内容复制到工具的左侧输入框,然后点“生成”按钮,即可自动将结构体生成出来。

该转换工具的下载地址:https://download.csdn.net/download/liuguangzhou123/88053077

至此,我的需求已完美解决!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/759620.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

x86架构ubuntu18下运行PS模拟器ePSXe

0. 环境 i7 虚拟机ubuntu18&#xff08;ubuntu22不行&#xff0c;会提示CURL_OPENSSL_3 not found&#xff09; 1. 安装依赖 sudo apt-get install libsdl-ttf2.0-0 sudo apt-get install libcurl3 2. 获取可执行文件 mkdir ePSXe cd ePSXe wget http://www.epsxe.com/files/…

MAYA精灵粒子一

group1.rotateYframe*10; particleShape1.spriteTwistPPrand(-90,90); 少 一个

Debug工具Trace32的ARM内存访问类型详解

关于Trace32的访问类型的基本概念可以参考博文&#xff1a; Trace32使用教程-访问类型&#xff08;Access Class&#xff09;_SOC罗三炮的博客-CSDN博客 本文将以ARMv8为基础&#xff0c;详解Trace32的内存访问类型。 内存访问类型描述A绝对寻址(物理地址)&#xff0c;即绕过…

实现复杂的按钮动画

今天主要是实现一个复杂的按钮提交动画效果&#xff0c;具体的关键变形环节如下&#xff1a; 初始环节 加载环节 展示结果环节 代码实现过程 1、html 页面机构 <button class"btn" data-btn>Submit</button> <div class"check_box">&…

初级与高级软件测试工程师的差距体现在哪些方面?如何成为高级测试工程师?

目录 初级测试工程师和高级测试工程师有什么区别或者差距呢&#xff1f; 一、不断的钻研 二、向同行或者他人学习 三、团队合作是更宽广的提升途径 四、了解你的客户和团队成员 软件测试工程师发展规划路线 我们都在努力追求卓越&#xff1a;希望在我们选择的职业中出类拔…

html2canvas将document DOM节点转换为图片,并下载到本地

html2canvas - Screenshots with JavaScripthttps://html2canvas.hertzen.com/了解一下&#xff0c;安装先 npm install --save html2canvas 用到的知识包括 前端用原生js编辑文件内容→创建生成文件(格式可以自定义)→下载文件_你挚爱的强哥的博客-CSDN博客会自动创建一个h…

服务器使用UDP通讯127.0.0.1测试成功连接服务器却通讯失败

首先看看本人情况 解释一下&#xff1a; 1&#xff1a;左边窗口是模拟服务程序&#xff0c;功能是收到消息后把消息打印出来&#xff0c;并把收到的消息再发回给发送消息的主机 2&#xff1a;右边窗口是模拟客户程序&#xff0c;功能是将输入的消息发送给服务程序的主机&…

【多线程例题】顺序打印abc线程

顺序打印-进阶版 方法一&#xff1a;三个线程竞争同一个锁&#xff0c;通过count判断是否打印 方法二&#xff1a;三个线程同时start&#xff0c;分别上锁&#xff0c;从a开始&#xff0c;打印后唤醒b 三个线程分别打印A&#xff0c;B&#xff0c;C 方法一&#xff1a;通过co…

前端笔记_OAuth规则机制下实现个人站点接入qq三方登录

文章目录 ⭐前言⭐qq三方登录流程&#x1f496;qq互联中心创建网页应用&#x1f496;配置回调地址redirect_uri&#x1f496;流程分析 ⭐思路分解⭐技术选型实现&#x1f496;技术选型&#xff1a;&#x1f496;实现 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本…

4.3.tensorRT基础(1)-实现模型的推理过程

目录 前言1. inference案例总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习 tensorRT 基础-实现模型的推理过程 课程大纲可…

深度学习——LSTM解决分类问题

RNN基本介绍 概述 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一种深度学习模型&#xff0c;主要用于处理序列数据&#xff0c;如文本、语音、时间序列等具有时序关系的数据。 核心思想 RNN的关键思想是引入了循环结构&#xff0c;允许…

JavaBeans

Code eamples ① Product.java (JavaBean Class) ② Bean.java (Servlet) ③ complie javac -encoding utf-8 -d ..\classes -sourcepath . chapter15\Bean.java ④ Tomcat ⑤ http://localhost:8080/book/chapter15/bean

flink水位线传播及任务事件时间

背景 本文来讲解一下flink的水位线传播及对其对任务事件时间的影响 水位线 首先flink是通过从源头生成水位线记录的方式来实现水位线传播的&#xff0c;也就是说水位线是嵌入在正常的记录流中的特殊记录&#xff0c;携带者水位线的时间戳&#xff0c;以下我们就通过图片的方…

Docker常用命令(三)

1、镜像命令 1、列出本地主机上的镜像 docker images [options]optiins说明&#xff1a; -a&#xff1a;列出本地所有的镜像&#xff08;包含历史映像层&#xff09; -q&#xff1a;只显示镜像ID2、搜索某个镜像信息 docker search [options] 镜像名字3、下载镜像 docker …

Kafka第二课-代码实战、参数配置详解、设计原理详解

一、代码实战 一、普通java程序实战 引入依赖 <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>2.4.1</version></dependency><dependency>&l…

windows环境hadoop报错‘D:\Program‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

Hadoop版本为2.7.3&#xff0c;在环境配置好后&#xff0c;检查hadoop安装版本&#xff0c;报如标题所示错误&#xff0c;尝试网上主流的几种方法均无效。 错误&#xff1a;windows环境hadoop报错’D:\Program’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 错误方…

Jackson使用

导入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0…

静态输出调节

1.理论部分 15. SISO反馈控制器设计 (6)&#xff1a;输出调节-静态反馈 Output Regulation - 知乎 (zhihu.com) 上述博客已经写的很好了&#xff0c;过多描述 2.仿真实验 3.参考理论 首先通过18式求解出X和U&#xff0c;然后设计一个让原系统初始稳定的控制律Kx&#xff0c;…

第二周习题

2.创建类MyDate,year属性和month属性,编写一个方法totalDays,该方法通过年份和月份判断该月一共有多少天,在主函数中接受用户输入年和月&#xff0c;调用该方法测试它. 这里考虑平年和闰年 “平年2月有28天。闰年的2月有29天 那么就有区别了 只要判断这一点就行了&#xff01;&…

框架开发使用注解处理器APT优雅提效

目录 概述1.什么是注解处理器APT2.应用场景3.如何使用3.1 创建注解API模块3.2 创建注解处理器模块3.3 使用注解 概述 在现在的很多开源框架中&#xff0c;我们经常能在源码中看到注解处理器的影子&#xff0c;比如我们熟悉的阿里的ARouter,Android开发中的替代findViewById神器…