JSON-02 CJsonObject 及 CJsonObject 的官方例程 demo.cpp

CJsonObject

1. CJsonObject 介绍

https://github.com/Bwar/CJsonObject

CJsonObject 是C++ CJSON 旧版本的新开发版本。CJsonObject最大的优点是重量轻、简单易用,开发效率很高。CJsonObject 比 CJSON 简单得多,更易于使用。

Bwar 首次使用 cJSON 是在 2013 年开发移动推送项目。当时,虽然cJSON很有用,但很容易忘记释放cJSON分配的内存。2014 年,Bwar 在开发另一个项目时再次使用 cJSON。为了提高cJSON的易用性,提高开发效率,对cJSON进行封装,支持64位整数。在CJsonObject的开发中,CJSON被稍微修改了。

5年来,CJsonObject在几个成功案例中验证了其稳定性。同时,CJsonObject集成到星云中,并得到广泛应用。

这里是一个维基常见问题的中文。

2. CJsonObject 的官方例程 demo.cpp

demo.cpp

#include <string>
#include <iostream>
#include "../CJsonObject.hpp"

int main()
{
    int iValue;
    std::string strValue;
    neb::CJsonObject oJson("{\"refresh_interval\":60,"
                        "\"dynamic_loading\":["
                            "{"
                                "\"so_path\":\"plugins/User.so\", \"load\":false, \"version\":1,"
                                "\"cmd\":["
                                     "{\"cmd\":2001, \"class\":\"neb::CmdUserLogin\"},"
                                     "{\"cmd\":2003, \"class\":\"neb::CmdUserLogout\"}"
                                "],"
                                "\"module\":["
                                     "{\"path\":\"im/user/login\", \"class\":\"neb::ModuleLogin\"},"
                                     "{\"path\":\"im/user/logout\", \"class\":\"neb::ModuleLogout\"}"
                                "]"
                             "},"
                             "{"
                             "\"so_path\":\"plugins/ChatMsg.so\", \"load\":false, \"version\":1,"
                                 "\"cmd\":["
                                      "{\"cmd\":2001, \"class\":\"neb::CmdChat\"}"
                                 "],"
                             "\"module\":[]"
                             "}"
                        "]"
                    "}");
     std::cout << oJson.ToString() << std::endl;
     std::cout << "-------------------------------------------------------------------" << std::endl;
     std::cout << oJson["dynamic_loading"][0]["cmd"][1]("class") << std::endl;
     oJson["dynamic_loading"][0]["cmd"][0].Get("cmd", iValue);
     std::cout << "iValue = " << iValue << std::endl;
     oJson["dynamic_loading"][0]["module"][0].Get("path", strValue);
     std::cout << "strValue = " << strValue << std::endl;
     std::cout << "-------------------------------------------------------------------" << std::endl;
     oJson.AddEmptySubObject("depend");
     oJson["depend"].Add("nebula", "https://github.com/Bwar/Nebula");
     oJson["depend"].AddEmptySubArray("bootstrap");
     oJson["depend"]["bootstrap"].Add("BEACON");
     oJson["depend"]["bootstrap"].Add("LOGIC");
     oJson["depend"]["bootstrap"].Add("LOGGER");
     oJson["depend"]["bootstrap"].Add("INTERFACE");
     oJson["depend"]["bootstrap"].Add("ACCESS");
     std::cout << oJson.ToString() << std::endl;
     std::cout << "-------------------------------------------------------------------" << std::endl;
     std::cout << oJson.ToFormattedString() << std::endl;
}

Makefile

CC = gcc
CXX = g++
CFLAGS = -g -O2 
CXXFLAG =  -O2 -Wall -ggdb -m64 -D_GNU_SOURCE=1 -D_REENTRANT -D__GUNC__ 

ARCH:=$(shell uname -m)

ARCH32:=i686
ARCH64:=x86_64

ifeq ($(ARCH),$(ARCH64))
SYSTEM_LIB_PATH:=/usr/lib64
else
SYSTEM_LIB_PATH:=/usr/lib
endif

VPATH = . ..
DIRS=$(VPATH)


INC := $(INC) 


LDFLAGS := $(LDFLAGS) -D_LINUX_OS_ 

CPP_SRCS = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp))
C_SRCS = $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
OBJS = $(patsubst %.cpp,%.o,$(CPP_SRCS)) $(patsubst %.c,%.o,$(C_SRCS)) $(patsubst %.cc,%.o,$(CC_SRCS))


TARGET = CJsonObjectTest

all: $(TARGET)

CJsonObjectTest:$(OBJS)
	$(CXX) -g -o $@ $^ $(LDFLAGS)

%.o:%.cpp
	$(CXX) $(INC) $(CXXFLAG) -c -o $@ $< $(LDFLAGS)
%.o:%.cc
	$(CXX) $(INC) $(CXXFLAG) -c -o $@ $< $(LDFLAGS)
%.o:%.c
	$(CC) $(INC) $(CXXFLAG) -c -o $@ $< $(LDFLAGS)
clean:
	rm -f $(OBJS)
	rm -f $(TARGET)
        

运行

[root@lwh demo]# make
g++   -O2 -Wall -ggdb -m64 -D_GNU_SOURCE=1 -D_REENTRANT -D__GUNC__  -c -o demo.o demo.cpp  -D_LINUX_OS_ 
g++   -O2 -Wall -ggdb -m64 -D_GNU_SOURCE=1 -D_REENTRANT -D__GUNC__  -c -o ../CJsonObject.o ../CJsonObject.cpp  -D_LINUX_OS_ 
gcc   -O2 -Wall -ggdb -m64 -D_GNU_SOURCE=1 -D_REENTRANT -D__GUNC__  -c -o ../cJSON.o ../cJSON.c  -D_LINUX_OS_ 
g++ -g -o CJsonObjectTest demo.o ../CJsonObject.o ../cJSON.o  -D_LINUX_OS_ 
[root@lwh demo]# ls
CJsonObjectTest  demo.cpp  demo.o  Makefile




[root@lwh demo]# ./CJsonObjectTest 
{"refresh_interval":60,"dynamic_loading":[{"so_path":"plugins/User.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdUserLogin"},{"cmd":2003,"class":"neb::CmdUserLogout"}],"module":[{"path":"im/user/login","class":"neb::ModuleLogin"},{"path":"im/user/logout","class":"neb::ModuleLogout"}]},{"so_path":"plugins/ChatMsg.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdChat"}],"module":[]}]}
-------------------------------------------------------------------
neb::CmdUserLogout
iValue = 2001
strValue = im/user/login
-------------------------------------------------------------------
{"refresh_interval":60,"dynamic_loading":[{"so_path":"plugins/User.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdUserLogin"},{"cmd":2003,"class":"neb::CmdUserLogout"}],"module":[{"path":"im/user/login","class":"neb::ModuleLogin"},{"path":"im/user/logout","class":"neb::ModuleLogout"}]},{"so_path":"plugins/ChatMsg.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdChat"}],"module":[]}],"depend":{"nebula":"https://github.com/Bwar/Nebula","bootstrap":["BEACON","LOGIC","LOGGER","INTERFACE","ACCESS"]}}
-------------------------------------------------------------------
{
        "refresh_interval":     60,
        "dynamic_loading":      [{
                        "so_path":      "plugins/User.so",
                        "load": false,
                        "version":      1,
                        "cmd":  [{
                                        "cmd":  2001,
                                        "class":        "neb::CmdUserLogin"
                                }, {
                                        "cmd":  2003,
                                        "class":        "neb::CmdUserLogout"
                                }],
                        "module":       [{
                                        "path": "im/user/login",
                                        "class":        "neb::ModuleLogin"
                                }, {
                                        "path": "im/user/logout",
                                        "class":        "neb::ModuleLogout"
                                }]
                }, {
                        "so_path":      "plugins/ChatMsg.so",
                        "load": false,
                        "version":      1,
                        "cmd":  [{
                                        "cmd":  2001,
                                        "class":        "neb::CmdChat"
                                }],
                        "module":       []
                }],
        "depend":       {
                "nebula":       "https://github.com/Bwar/Nebula",
                "bootstrap":    ["BEACON", "LOGIC", "LOGGER", "INTERFACE", "ACCESS"]
        }
}
[root@lwh demo]# 


3. CJsonObject 使用中遇到的问题


3.1 如何遍历json的key,并取其value?

std::string strTraversingKey;
std::string strTraversingValue;

// while(oJson.GetKey(strTraversingKey)){}
// 每次!从oJson对象中取出一个key并把key设置进strTraversingKey
// 获取成功就返回true,当遍历完所有的key后,返回false
while (oJson.GetKey(strTraversingKey))
{
	// oJson.Get(strTraversingKey, strTraversingValue) 
	// 从oJson对象中取出key=strTraversingKey对应的value,
	// 并把value设置进strTraversingValue
     if (oJson.Get(strTraversingKey, strTraversingValue))
     {
          std::cout << strTraversing << "  :  " << strTraversingValue << std::endl;
     }
}

GetKey()遍历不适用于数组,对json数组调用GetKey()将直接返回false。

调用GetKey()函数循环遍历获取当前所在层次的json key,GetKey()返回false表示已取完最后一个key,下次遍历再调用GetKey()将重新从第一个key开始获取。换一种说法,GetKey()遍历json key的返回结果为:true,true,true … true,false; true,true,true … true,false; true,true,true … true,false; 想要遍历多少轮完全由用户自己决定。

如果需要中断一次遍历并重新开始,可以调用ResetTraversing()函数重置遍历。

std::string strTraversingKey;
std::string strTraversingValue;
while(oJson.GetKey(strTraversingKey))
{
    if (strTraversingKey == "Auguest")
    {
        oJson.ResetTraversing();
        break;
    }
    if (oJson.Get(strTraversingKey, strTraversingValue))
    {
        std::cout << strTraversing << "  :  " << strTraversingValue << std::endl;
    }
}

// 因为上一个遍历中断时调用了ResetTraversing(),所以本次遍历又是从第一个key开始。如果上一个遍历中断时未调用ResetTraversing(),那这次遍历将是从上次终端的位置继续,这通常不是遍历的预期结果,因此,中断遍历时记得ResetTraversing()。
while(oJson.GetKey(strTraversingKey))
{
    if (oJson.Get(strTraversingKey, strTraversingValue))
    {
        std::cout << strTraversing << "  :  " << strTraversingValue << std::endl;
    }
}

__注意:__对Json当前层次的key进行Add()或Delete()操作,将导致当前遍历失效,下次调用GetKey()将获取key从头开始。


3.2 Replace一个key时,是否需要原value类型与替换后value类型一致?

Replace()函数对key进行替换,跟value类型无关。

把一个value为int的替换为value为string,或将value替换为object或array都是可以的。但如非必要,建议替换后的value类型跟替换前的value类型相同。


3.3 []和()的重载有什么区别,为什么要重载这两个操作符?

[]的重载是操作JsonObject或JsonArray的,为了方便一层一层往下取嵌套的json,不适用于string、int等基本json类型;

()的重载是Get()系列函数的更便捷的调用,如果十分肯定key是存在的不需要通过Get()的返回值判断是否获取成功,调用()比调用Get()编码要快,不适用于操作JsonObject或JsonArray。

[]和()返回值是不一样的,两者不能混用。


3.4 如何用CJsonObject创建类似以下二维数组?

{
    "test":[
        [{"test":1}],
        [{"test":2}]
    ]
}

CJsonObject对多层嵌套json的操作非常灵活方便,对嵌套json的生成和读取有许多种灵活用法。

neb::CJsonObject oTest;
oTest.AddEmptySubArray("test");
for (int i = 1; i < 3; ++i)
{
    neb::CJsonObject oDimension1;
    neb::CJsonObject oDimension2;
    oDimension2.Add("test", i);
    oDimension1.Add(oDimension2);
    oTest["test"].Add(oDimension1);
}
std::cout << oTest.ToString() << std::endl;

3.5 请问一下使用CJsonObject如何创建如下形式的数组?

{
    "employees": [
        { "firstName":"John" , "lastName":"Doe" },
        { "firstName":"Anna" , "lastName":"Smith" },
        { "firstName":"Peter" , "lastName":"Jones" }
    ]
}

这里给出三种生成上述json数组的方式:

neb::CJsonObject oJson;
oJson.AddEmptySubArray("employees");
oJson["employees"].Add(neb::CJsonObject("{\"firstName\":\"John\" , \"lastName\":\"Doe\"}"));
oJson["employees"].Add(neb::CJsonObject("{\"firstName\":\"Anna\" , \"lastName\":\"Smith\"}"));
oJson["employees"].Add(neb::CJsonObject("{\"firstName\":\"Peter\" , \"lastName\":\"Jones\"}"));
neb::CJsonObject oJson;
oJson.AddEmptySubArray("employees");
oJson["employees"].Add(neb::CJsonObject("{}"));
oJson["employees"][0].Add("firstName", "John");
oJson["employees"][0].Add("lastName", "Doe");
oJson["employees"].Add(neb::CJsonObject("{}"));
oJson["employees"][1].Add("firstName", "Anna");
oJson["employees"][1].Add("lastName", "Smith");
oJson["employees"].Add(neb::CJsonObject("{}"));
oJson["employees"][2].Add("firstName", "Peter");
oJson["employees"][2].Add("lastName", "Jones");
neb::CJsonObject oJson;
neb::CJsonObject oJohn;
neb::CJsonObject oAnna;
neb::CJsonObject oPeter;
oJohn.Add("firstName", "John");
oJohn.Add("lastName", "Doe");
oAnna.Add("firstName", "Anna");
oAnna.Add("lastName", "Smith");
oPeter.Add("firstName", "Peter");
oPeter.Add("lastName", "Jones");
oJson.AddEmptySubArray("employees");
oJson["employees"].Add(oJohn);
oJson["employees"].Add(oAnna);
oJson["employees"].Add(oPeter);


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: msp-exp432p401r官方程是指官方提供的用于MSP-EXP432P401R开发板的示程序。这些示程序包括各种应用场景,如LED控制、ADC采集、PWM输出、UART通信等。开发者可以通过学习这些示程序,了解MSP-EXP432P401R的各种功能和使用方法,从而更好地开发自己的应用程序。 ### 回答2: msp-exp432p401r是一款德州仪器推出的基于ARM Cortex-M4内核的开发板,它集成了许多常用的外设,包括GPIO、UART、SPI、I2C等,可以用来进行嵌入式系统开发和物联网应用开发。它的官方程提供了一些基本功能的示代码,可以帮助开发者快速熟悉开发板的使用方法和应用开发流程。 首先,官方程提供了Blink LED示代码,这个子演示了如何使用GPIO控制LED的闪烁,是所有硬件开发的基础,因为如果不能掌握GPIO的使用方法,在后续的开发中会遇到很多问题。 其次,官方程还提供了一些与串口通信相关的代码,比如Echo示和Loopback示,这些代码演示了如何使用UART通信,UART在嵌入式和物联网应用中常用于与传感器、终端设备、远程服务器等进行通信。 除了GPIO和UART外,官方程还提供了一些其他的外设操作代码,比如SPI和I2C总线的读写,以及PWM输出控制等,这些代码可以帮助开发者学习如何使用开发板的外设进行各种应用开发。 总之,msp-exp432p401r官方程提供了一些基本的入门代码,可以帮助开发者快速入门嵌入式和物联网应用开发,但是对于更为复杂的应用,还需要自己进行深入学习和开发。 ### 回答3: msp-exp432p401r是一款TI公司推出的基于ARM Cortex-M4内核的低功耗微控制器开发板,官方提供了一系列程供开发者参考。这些程可以在TI官网上下载,包括但不限于以下几个方面。 1. 时钟配置:该程用于配置MCU的时钟系统。根据不同的应用场景,可以选择不同的时钟源和频率。如,如果需要节约功耗,可以选择低速时钟源和较低的频率。 2. GPIO控制:该程用于控制GPIO(通用输入/输出)引脚。学习如何使用GPIO口可以实现复杂的控制任务,如控制LED灯、读取按键状态等等。 3. ADC采集:该程用于配置和启动MSP432的ADC(模数转换器),并通过DMA(直接内存访问)实现持续的ADC数据采集。ADC采集可以用于测量温度、光照强度等模拟信号。 4. UART通信:该程用于通过MSP432的UART(通用异步收发传输)模块实现串口通信。串口通信是一种常见的通信方式,可以实现MCU与其他外部设备(如PC机)之间的数据传输。 5. I2C通信:该程用于通过MSP432的I2C(串行外设接口)模块实现I2C通信。I2C通信是一种常见的通信方式,可以实现MCU与其他IC芯片之间的数据传输。 总的来说,MSP-EXP432P401R官方程涵盖了MCU开发的各方面内容,可以帮助开发者快速上手MCU编程并实现自己的项目。但需要注意的是,这些程仅仅只是提供了基础的代码示,实际开发需要根据具体应用需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值