当前位置: 首页 > 工具软件 > CJsonObject > 使用案例 >

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

漆雕原
2023-12-01

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);


 类似资料: