C++对象的JSON序列化与反序列化探索
来源:互联网 发布:python可以开发app吗 编辑:程序博客网 时间:2024/05/16 06:22
一:背景
作为一名C++开发人员,我一直很期待能够像C#与JAVA那样,可以轻松的进行对象的序列化与反序列化,但到目前为止,尚未找到相对完美的解决方案。
本文旨在抛砖引玉,期待有更好的解决方案;同时向大家寻求帮助,解决本文中未解决的问题。
二:相关技术介绍
本方案采用JsonCpp来做具体的JSON的读入与输出,再结合类成员变量的映射,最终实现对象的JSON序列化与反序列化。
本文不再讨论如何使用JsonCpp,此处将作者在应用时发现的两处问题进行说明:
1. 下载Jsoncpp,编译其lib,并且引用到项目中,发现有如下错误:
错误1 fatal error C1083: Cannot open compiler generated file: '../../build/vs71/release/lib_json\json_writer.asm': No such file or directory c:\Documents and Settings\Administrator\jsoncpp-src-0.6.0-rc2\jsoncpp-src-0.6.0-rc2\src\lib_json\json_writer.cpp
错误2 fatal error LNK1257:代码生成失败 JasonSerialize
可以通过在修改LIB库项目的属性解决,如下图[关闭汇编输出]:
2. JSONCPP官网首页的下载版本是0.5.0,此版本不支持Int64等类型,下载版本jsoncpp-src-0.6.0-rc2后即可支持.
三:一个基于JsonCpp的序列化与反序列化基类
先看代码:
#pragma once#include <string>#include <vector>#include "json/json.h"using std::string;using std::vector;struct CJsonObejectBase{protected:enum CEnumJsonTypeMap{asInt = 1,asUInt,asString,asInt64,asUInt64,};public:CJsonObejectBase(void){}public:virtual ~CJsonObejectBase(void){}string Serialize(){Json::Value new_item; int nSize = m_listName.size();for (int i=0; i < nSize; ++i ){void* pAddr = m_listPropertyAddr[i];switch(m_listType[i]){case asInt:new_item[m_listName[i]] = (*(INT*)pAddr);break;case asUInt:new_item[m_listName[i]] = (*(UINT*)pAddr);break;case asInt64:new_item[m_listName[i]] = (*(LONGLONG*)pAddr);break;case asUInt64:new_item[m_listName[i]] = (*(ULONGLONG*)pAddr);break;case asString:new_item[m_listName[i]] = (*(string*)pAddr);default://我暂时只支持这几种类型,需要的可以自行添加 break;}}Json::FastWriter writer; std::string out2 = writer.write(new_item); return out2;}bool DeSerialize(const char* str){Json::Reader reader; Json::Value root;if (reader.parse(str, root)){ int nSize = m_listName.size();for (int i=0; i < nSize; ++i ){void* pAddr = m_listPropertyAddr[i];switch(m_listType[i]){case asInt:(*(INT*)pAddr) = root.get(m_listName[i], 0).asInt();break;case asUInt:(*(UINT*)pAddr) = root.get(m_listName[i], 0).asUInt();break;case asInt64:(*(LONGLONG*)pAddr) = root.get(m_listName[i], 0).asInt64();break;case asUInt64:(*(ULONGLONG*)pAddr) = root.get(m_listName[i], 0).asUInt64();break;case asString:(*(string*)pAddr) = root.get(m_listName[i], "").asString();default://我暂时只支持这几种类型,需要的可以自行添加 break;}}return true;}return false;}protected:void SetProperty(string name, CEnumJsonTypeMap type, void* addr){m_listName.push_back(name);m_listPropertyAddr.push_back(addr);m_listType.push_back(type);}virtual void SetPropertys() = 0;vector<string> m_listName;vector<void*> m_listPropertyAddr;vector<CEnumJsonTypeMap> m_listType;};
此类主要有三个函数:Serialize、DeSerialize及 SetPropertys、SetProperty,其中前两个函数主要是用来实现对象的序列化与反序列化;SetPropertys是一个纯虚函数,如果一个类需要具备序列化功能,只需要从此类继承,同时调用SetProperty函数,将各个字段的属性进行设置即可。
四:使用对象的序列化及反序列化功能
要使对象具体相应功能,需要继承上述的基类,如下:
struct CTestStruct : public CJsonObejectBase{CTestStruct(){SetPropertys();}ULONGLONG MsgID;string MsgTitle;string MsgContent;protected://子类需要实现此函数,并且将相应的映射关系进行设置 virtual void SetPropertys(){SetProperty("MsgID", asUInt64, &MsgID);SetProperty("MsgTitle", asString, &MsgTitle);SetProperty("MsgContent", asString, &MsgContent);}};
继承后,我们可以使用如下代码来进行测试
序列化:
void CJasonSerializeDlg::OnBnClickedOk(){CTestStruct stru;stru.MsgID = 11223344;stru.MsgTitle = "黑黑";stru.MsgContent = "哈哈";CString strTest = stru.Serialize().c_str();AfxMessageBox(strTest);}
结果:
反序列化:
void CJasonSerializeDlg::OnBnClickedOk2(){const char* pstr = "{\"MsgContent\":\"哈哈22\",\"MsgID\":11111111111111111,\"MsgTitle\":\"黑黑22\"}";CTestStruct stru;stru.DeSerialize(pstr);CString strShow = "";strShow.Format("MsgID:%I64u\r\nMsgTile:%s\r\nMsgContent:%s", stru.MsgID, stru.MsgTitle.c_str(), stru.MsgContent.c_str());AfxMessageBox(strShow);}
结果:
五:未解决的问题
1. 目前我对属性的映射采用的是vector顺序映射的方式,这样必需在子类中对每一个属性进行设置,是否有宏的策略可以使这部分工作更加轻松?
2. 目前只支持整型、64位整型及字符串类型,需要支持其他类型,可以在基类中添加映射即可。
3. 目前只支持单个简单对象[其属性均为简单类型]的序列化与反序列化,暂时未考虑如何支持复杂的,如内部包含其他的复杂对象、包含数组等情况。
完整代码请于如下链接下载:
http://download.csdn.net/detail/tragicguy/5630473
- C++对象的JSON序列化与反序列化探索完结-列表的序列化与反序列化
- C++对象的JSON序列化与反序列化探索
- C++对象的JSON序列化与反序列化探索续-复杂对象的序列化与反序列化
- JSON序列化与反序列化对象
- JSON对象序列化与反序列化
- JSON时间对象序列化与反序列化<Timestamp>
- C# 对象JSON序列化与反序列化
- C++序列化与反序列化的简单探索
- JSON 对象序列化、反序列化
- C#序列、反序列化json对象
- Json(c#)序列化与反序列化
- 【转】c#--json序列化与反序列化
- POJO与JSON的序列化与反序列化
- Json序列化 与反序列化
- JSON序列化与反序列化
- JSON序列化与反序列化
- Json序列化与反序列化
- Json序列化与反序列化
- ajax学习篇9
- 电子商务基础2
- 进程管理--回收僵尸态子进程
- Building MFC application with /MD[d] (CRT dll version)requires MFC shared dll version~~~~ .
- 关于ESET占用CPU严重 的解决方案||ESET CPU 100%||用迅雷时ESET占用CPU(6月22日再次更新)
- C++对象的JSON序列化与反序列化探索
- Sql2008获取表说明
- jsp页面使用js控制文本框只读,并且按下backspace删除按钮后停在原页面
- 何为数据库、SQL
- 移除JSON对象中的某个属性
- 关于字符集和Unicode的相关知识
- 第10课pl/sql语言之创建 包和过程等
- 【读书笔记】C程序中常见的内存操作有关的典型编程错误
- ios学习之生命周期