C++ json解决方案

时间:2021-10-14 04:01:16

前段时间用到C++来封装com 因此从数据转换上我采用的Json来当两种语言的传递方式,现做下json的序列化与反序列化方案的总结:

Rapidjson

文档地址:http://rapidjson.org/zh-cn/

使用体会:比C# 现有的各类Json库相比调用麻烦需要特别清楚整体结构。

序列化代码:

                rapidjson::Document jsonDoc;
		rapidjson::Document::AllocatorType &allocator = jsonDoc.GetAllocator(); //获取分配器

		jsonDoc.SetArray();
		
		for(int i=0;i< facesPoint.size();i++)
		{
			Value faceArray(kObjectType);
			Value jawArray(kArrayType);
			for(int j=0;j<facesPoint[i].jaw.size();j++)
			{
				Value pointobj(kObjectType);
				pointobj.AddMember("x", facesPoint[i].jaw[j].X, allocator);
				pointobj.AddMember("y", facesPoint[i].jaw[j].Y, allocator);
				jawArray.PushBack(pointobj, allocator);
			}
			faceArray.AddMember("jaw", jawArray, allocator);

			Value leftBroArray(kArrayType);
			for (int j = 0; j<facesPoint[i].leftBrow.size(); j++)
			{
				Value pointobj(kObjectType);
				pointobj.AddMember("x", facesPoint[i].leftBrow[j].X, allocator);
				pointobj.AddMember("y", facesPoint[i].leftBrow[j].Y, allocator);
				leftBroArray.PushBack(pointobj, allocator);
			}
			faceArray.AddMember("leftBrow", leftBroArray, allocator);

			Value leftEyeArray(kArrayType);
			for (int j = 0; j<facesPoint[i].leftEye.size(); j++)
			{
				Value pointobj(kObjectType);
				pointobj.AddMember("x", facesPoint[i].leftEye[j].X, allocator);
				pointobj.AddMember("y", facesPoint[i].leftEye[j].Y, allocator);
				leftEyeArray.PushBack(pointobj, allocator);
			}
			faceArray.AddMember("leftEye", leftEyeArray, allocator);

			Value mouthArray(kArrayType);
			for (int j = 0; j<facesPoint[i].mouth.size(); j++)
			{
				Value pointobj(kObjectType);
				pointobj.AddMember("x", facesPoint[i].mouth[j].X, allocator);
				pointobj.AddMember("y", facesPoint[i].mouth[j].Y, allocator);
				mouthArray.PushBack(pointobj, allocator);
			}
			faceArray.AddMember("mouth", mouthArray, allocator);

			Value mouth2Array(kArrayType);
			for (int j = 0; j<facesPoint[i].mouth2.size(); j++)
			{
				Value pointobj(kObjectType);
				pointobj.AddMember("x", facesPoint[i].mouth2[j].X, allocator);
				pointobj.AddMember("y", facesPoint[i].mouth2[j].Y, allocator);
				mouth2Array.PushBack(pointobj, allocator);
			}
			faceArray.AddMember("mouth2", mouth2Array, allocator);

			Value noseArray(kArrayType);
			for (int j = 0; j<facesPoint[i].nose.size(); j++)
			{
				Value pointobj(kObjectType);
				pointobj.AddMember("x", facesPoint[i].nose[j].X, allocator);
				pointobj.AddMember("y", facesPoint[i].nose[j].Y, allocator);
				noseArray.PushBack(pointobj, allocator);
			}
			faceArray.AddMember("nose", noseArray, allocator);

			Value rightBrowArray(kArrayType);
			for (int j = 0; j<facesPoint[i].rightBrow.size(); j++)
			{
				Value pointobj(kObjectType);
				pointobj.AddMember("x", facesPoint[i].rightBrow[j].X, allocator);
				pointobj.AddMember("y", facesPoint[i].rightBrow[j].Y, allocator);
				rightBrowArray.PushBack(pointobj, allocator);
			}
			faceArray.AddMember("rightBrow", rightBrowArray, allocator);

			Value rightEyeArray(kArrayType);
			for (int j = 0; j<facesPoint[i].rightEye.size(); j++)
			{
				Value pointobj(kObjectType);
				pointobj.AddMember("x", facesPoint[i].rightEye[j].X, allocator);
				pointobj.AddMember("y", facesPoint[i].rightEye[j].Y, allocator);
				rightEyeArray.PushBack(pointobj, allocator);
			}
			faceArray.AddMember("rightEye", rightEyeArray, allocator);

			jsonDoc.PushBack(faceArray, allocator);
		}
	

		rapidjson::StringBuffer buffer;
		rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
		jsonDoc.Accept(writer);

 JSON for Modern C++

文档地址:https://github.com/nlohmann/json

使用体会:目前为止找到比较简单粗暴的json解决方案代码也简单易懂

序列化前必要的模版声明

 

namespace NaughtyKidFaceRectangle
{
	struct FaceRectangle
	{
	    public:
		double top;
		double bottom;
		double left;
		double right;
		double width;
		double height;
		FaceRectangle() {};
		FaceRectangle(double _top, double _bottom, double _left, double _right, double _width, double _height)
		{
			top = _top;
			bottom = _bottom;
			left = _left;
			right = _right;
			width = _width;
			height = _height;
		}

	};

	inline   void to_json(nlohmann::json& j, const FaceRectangle& p)
	{
		j = nlohmann::json
		{
			{"top", p.top},
			{ "bottom", p.bottom} ,
			{ "left", p.left },
			{ "right", p.right },
			{ "width", p.width },
			{ "height", p.height }
		};
	}

	inline   void from_json(const nlohmann::json& j, FaceRectangle& p)
	{
		p.top = j.at("top").get<double>();
		p.bottom = j.at("bottom").get<double>();
		p.left = j.at("left").get<double>();
		p.right = j.at("right").get<double>();
		p.width = j.at("width").get<double>();
		p.height = j.at("height").get<double>();

	}
}

namespace NaughtyKid
{
	struct  NaughtyKidPoint
	{

	public:
		NaughtyKidPoint() {};
		NaughtyKidPoint(double _x, double _y) { x = _x; y = _y; }
		NaughtyKidPoint(double _x, double _y, int _index) { x = _x; y = _y; index = _index; }

		double x;
		double y;
		int index;


	};

	void to_json(nlohmann::json& j, const NaughtyKidPoint& p) {
		j = nlohmann::json{
			{
				"x", p.x
			},{ "y", p.y } ,{"index",p.index}};
	}

	void from_json(const nlohmann::json& j, NaughtyKidPoint& p) {
		p.x = j.at("x").get<double>();
		p.y = j.at("y").get<double>();
		p.index = j.at("index").get<double>();
	}
}


using namespace NaughtyKid;
namespace dlib_face
{
	struct  dlib_face
	{
	    public:
		std::vector<NaughtyKidPoint> jaw; //下巴
		std::vector<NaughtyKidPoint> rightBrow; //右眉毛
		std::vector<NaughtyKidPoint> leftBrow;  //左眉毛
		std::vector<NaughtyKidPoint> nose; //鼻子
		std::vector<NaughtyKidPoint> rightEye; //右眼
		std::vector<NaughtyKidPoint> leftEye; //左眼
		std::vector<NaughtyKidPoint> mouth; //上嘴唇
		std::vector<NaughtyKidPoint> mouth2; //下嘴唇

		double face_width;
		double face_height;
	    
	};

	struct dlib_facedetails
	{
	   public:
		   dlib_face featurepoint;
		   double angleofface;		
	};

	inline void to_json(nlohmann::json& j, const dlib_facedetails& p)
	{
		j = nlohmann::json
		{
			{"featurepoint",p.featurepoint},
			{"angleofface",p.angleofface}
		};
	}

	inline void from_json(const nlohmann::json& j, dlib_facedetails& p)
	{
		p.featurepoint = j.at("featurepoint").get<dlib_face>();
		p.angleofface = j.at("angleofface").get<double>();
	}

	inline void to_json(nlohmann::json& j, const dlib_face& p) {
		j = nlohmann::json{
			{ "jaw", p.jaw },
			{ "rightBrow", p.rightBrow },
			{ "leftBrow", p.leftBrow },
			{ "nose",p.nose },
			{ "rightEye",p.rightEye },
			{ "leftEye",p.leftEye },
			{ "mouth",p.mouth },
			{ "mouth2",p.mouth2 },
			{"face_width",p.face_width},
			{"face_height",p.face_height}

		};
	}

	inline void from_json(const nlohmann::json& j, dlib_face& p) {
		p.jaw = j.at("jaw").get<std::vector<NaughtyKidPoint>>();
		p.rightBrow = j.at("rightBrow").get<std::vector<NaughtyKidPoint>>();
		p.leftBrow = j.at("leftBrow").get<std::vector<NaughtyKidPoint>>();
		p.nose = j.at("nose").get<std::vector<NaughtyKidPoint>>();
		p.rightEye = j.at("rightEye").get<std::vector<NaughtyKidPoint>>();
		p.leftEye = j.at("leftEye").get<std::vector<NaughtyKidPoint>>();
		p.mouth = j.at("mouth").get<std::vector<NaughtyKidPoint>>();
		p.mouth2 = j.at("mouth2").get<std::vector<NaughtyKidPoint>>();
		p.face_width = j.at("face_width").get<double>();
		p.face_height = j.at("face_height").get<double>();
	}
}

序列化部分代码:

 

        std::vector<NaughtyKidFaceRectangle::FaceRectangle> faces;

	nlohmann::json j = faces;

	std::ostringstream oss;

	oss << j << endl;

 

 反序列化代码:

const auto js = nlohmann::json::parse(sp.c_str());
			
const dlib_face::dlib_face ddlibfaces = js;