C++ json解决方案
前段时间用到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;