上一篇,同大家一起分享了QJson的移植(Qt4.8.3)、使用技巧(如何移植和使用QJson),本篇我们来熟悉下使用Jsoncpp生成和解析Json字符串。当然作为Qt的狂热爱好者,我还是会继续改造Jsoncpp项目,来一个Qt项目版。需要下载对应项目资源的朋友,可以在文末点击链接下载。回归到正题上来。
下载路径 https://sourceforge.net/projects/jsoncpp/
我们还是先改造下项目,使jsoncpp变成我们熟悉的Qt项目,通过Qt构建和编译生成Jsoncpp.dll库文件。
1、在下载和解压jsoncpp-master源码后,我们自己定义一个jsoncpp的Qt项目目录。 先将源码中 include目录下的json文件夹 拷贝到 jsoncpp文件夹中,然后将src目录下lib_json中的所有文件拷贝到jsoncpp下的 json 文件夹中。如下图:
2、新建一个.pro文件,编写文件内容如下:
#-------------------------------------------------
#
# Project created by QtCreator 2017-12-09T14:36:16
#
#-------------------------------------------------
TARGET = jsoncpp
TEMPLATE = lib
CONFIG += shared
CONFIG += dll
CONFIG += exceptions
# 指定包含的头文件路径,否则对应使用<>引用的头文件会报错
INCLUDEPATH += ./
# 指定生成库的目标文件路径
DESTDIR = ./lib
#Mingw
#win32-g++{
# BINDIR = ../win32-gcc-bin
#}
##Vs2010
#win32-msvc2010{
# BINDIR = ../../vs2010-bin
#}
##arm-linux
#linux-arm-g++{
# BINDIR = ../arm-linux-gcc-bin
# DEFINES += __NO_PRECOMPILED_HEADER__
# DEFINES += _TTY_POSIX_
#}
#CONFIG(debug, debug|release){
# DESTDIR = $$BINDIR/debug
#}else{
# DESTDIR = $$BINDIR/release
#}
SOURCES += \
json/json_internalarray.inl \
json/json_internalmap.inl \
json/json_reader.cpp \
json/json_value.cpp \
json/json_valueiterator.inl \
json/json_writer.cpp
HEADERS +=\
json/autolink.h \
json/config.h \
json/features.h \
json/forwards.h \
json/json.h \
json/json_batchallocator.h \
json/reader.h \
json/value.h \
json/writer.h
3、使用Qt打开我们的jsoncpp.pro工程文件,可取消影子构建,然后构建和编译项目,在lib目录下可生成对应的.dll 和.a 库文件。
1、首先新建一个jsoncppTest的Qt控制台项目。运行下项目。然后我们将jsoncpp.dll和.a库文件拷贝到 jsoncppTest项目的Relaese目录下。在pro文件中添加库文件链接。
#-------------------------------------------------
#
# Project created by QtCreator 2020-05-19T08:50:19
#
#-------------------------------------------------
QT += core
QT -= gui
INCLUDEPATH += ./json
TARGET = jsoncppTest
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
LIBS += -L$$PWD/release/ -ljsoncpp
2、准备工作已经做好,接下来我们在main.cpp中进行功能测试。因为比较简单,不做过多解释,直接看代码吧。
#include
#include "json/json.h"
#include "json/reader.h"
#include "json/value.h"
#include "json/writer.h"
#include
#include
// deamon以如下json的生成和解析为例,来演示jsoncpp的用法
/*
* QString json("{"
"\"encoding\" : \"UTF-8\","
"\"plug-ins\" : [\"python\",\"c++\",\"ruby\"],"
"\"types\":[{\"A\":1,\"B\":5},{\"A\":2,\"B\":6}],"
"\"indent\" : { \"length\" : 3, \"use_space\" : true }"
"}");
*/
QString generate_json_string(){
Json::Value root;
Json::Value arr_plug;
Json::Value arr_types;
Json::Value val;
// 处理json对象
// [1] encoding
root["encoding"] = "UTF-8";
// [2] indent
root["indent"]["length"] = 3;
root["indent"]["use_space"] = true;
// 处理json数组
// [3] plug-ins
arr_plug.append("python");
arr_plug.append("c++");
arr_plug.append("ruby");
root["plug-ins"] = arr_plug;
// [4] types
val["A"] = 1;
val["B"] = 5;
arr_types.append(val);
val["A"] = 2;
val["B"] = 6;
arr_types.append(val);
root["types"] = arr_types;
// 生成json字符串
Json::StyledWriter sw;
QString string = QString::fromStdString(sw.write(root));
return string;
}
void parsing_json_string(QString json_string){
Json::Reader reader;
Json::Value value;
if(reader.parse(json_string.toStdString(),value))
{
/*
* Int asInt() const;
* UInt asUInt() const;
* double asDouble() const;
* bool asBool() const;
*
* bool isNull() const;
* bool isBool() const;
* bool isInt() const;
* bool isUInt() const;
* bool isIntegral() const;
* bool isDouble() const;
* bool isNumeric() const;
* bool isString() const;
* bool isArray() const;
* bool isObject() const;
bool isConvertibleTo( ValueType other ) const;
*/
/// [1] 解析json对象
QString encoding = QString::fromStdString(value["encoding"].asString());
// 在转换前,可以先判断下对象的数据类型然后再做对应转换,避免出现错误
int indent_length = value["indent"]["length"].isInt() ? value["indent"]["length"].asInt() : 0;
bool indent_use_sapce = value["indent"]["use_space"].asBool();
/// [2] 解析json数组
const Json::Value arrayObj_plug = value["plug-ins"];
qDebug() << "plu-ins :[";
for(unsigned int i = 0;i < arrayObj_plug.size(); ++i)
{
qDebug () << "\t"<< QString::fromStdString(arrayObj_plug[i].asString()) << ",";
}
qDebug() << "],";
const Json::Value arrayObj_types = value["types"];
qDebug() << "type: [" ;
for(unsigned int i = 0;i < arrayObj_types.size(); ++i)
{
qDebug() << "{" ;
qDebug () << "\t" << "A:" << arrayObj_types[i]["A"].asInt();
qDebug () << "\t" << "B:" << arrayObj_types[i]["B"].asInt();
qDebug() << "},";
}
qDebug() << "],";
qDebug() << "encoding :" << encoding;
qDebug() << "indent_length :" << indent_length;
qDebug() << "indent_use_sapce :" << indent_use_sapce;
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "*************************************";
QString string = generate_json_string();
qDebug() << generate_json_string();
qDebug() << "*************************************";
parsing_json_string(string);
return a.exec();
}
打印输出结果如下:
*************************************
"{
"encoding" : "UTF-8",
"indent" : {
"length" : 3,
"use_space" : true
},
"plug-ins" : [ "python", "c++", "ruby" ],
"types" : [
{
"A" : 1,
"B" : 5
},
{
"A" : 2,
"B" : 6
}
]
}
"
*************************************
plu-ins :[
"python" ,
"c++" ,
"ruby" ,
],
type: [
{
A: 1
B: 5
},
{
A: 2
B: 6
},
],
encoding : "UTF-8"
indent_length : 3
indent_use_sapce : true
从输出结果来看,jsoncpp也可以灵活的生成和解析jsoncpp字符串,比QJson似乎更加容易上手一些呢。
那么,我们来简单对比下jsoncpp和QJson。
(1)格式上,jsoncpp相对于QJson生成的Json字符串来说,就是多了很多空格和换行符号,优点是 打印输出的json格式十分直观,缺点就是字符串长度变大,占用更多的存储空间,如果在网络传输中直接使用,会浪费较多的流量。所以如果使用Jsoncpp,我们实际项目中会对字符串进行优化,除空格和换行,甚至会使用字符串压缩技术,这部分我们在后面的文章中讲。
(2)QJson依赖于Qt组件,在Qt项目中使用还是很好的,但这也是他存在的局限性。在非Qt项目中,当然建议使用jsoncpp
附: 如何在嵌入式设备中使用 jsponcpp?
1、库文件编译如下,使用方法参照如上测试案例。
1、安装 scons
$ sudo apt-get install scons
$ scons platform=linux-gcc
2、编译jsconcpp库文件
mkdir arm_jsoncpp
cp -r include/json arm_jsoncpp/
cp src/lib_json/* arm_jsoncpp/
cd arm_jsoncpp/
#create static dll
#arm-arago-linux-gnueabi-g++ -c *.cpp -fPIC
#ar cr libjsoncpp.a *.o
#create dynamicall dll
arm-arago-linux-gnueabi-g++ -shared -fPIC *.cpp -o libjsoncpp.so
注意:在编译过程中如果出现以下的错误:
json_reader.cpp:1:25: fatal error: json/reader.h: No such file or directory
compilation terminated.
json_value.cpp:2:24: fatal error: json/value.h: No such file or directory
compilation terminated.
json_writer.cpp:1:25: fatal error: json/writer.h: No such file or directory
compilation terminated.
【解决方法:】头文件的路径不对。将 修改成"json/reader.h";其他几个文件也对应处理。