序列化对象C++对象的JSON序列化与反序列化探索

摘要:
新手帖子在很多方面都是新的。请原谅我的任何错误。欢迎批评正义。作为一名C++开发人员,我一直期待着像C#和Java这样的对象的轻松序列化和反序列化。但到目前为止,还没有找到相对完美的解决方案。

新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正

    一:背景

    作为一名C++开发人员,我始终很期待能够像C#JAVA那样,可以省力的进行对象的序列化与反序列化,但到现在为止,还没有找到相对完美的处理方案。

    本文旨在抛砖引玉,期待有更好的处理方案;同时向大家追求帮助,处理本文中未处理的问题。 

    二:相干技术介绍

    本方案采取JsonCpp来做具体的JSON的读入与输出,再结合类成员变量的映射,终究实现对象的JSON序列化与反序列化。

    本文不再探讨如何使用JsonCpp,此处将作者在应用时发现的两处问题进行说明:

    1.       下载Jsoncpp,编译其lib,并且引用到项目中,发现有如下错误:

    错误1       fatal error C1083: Cannot open compiler generated file: '../../build/vs71/release/lib_jsonjson_writer.asm': No such file or directory       c:Documents and SettingsAdministratorjsoncpp-src-0.6.0-rc2jsoncpp-src-0.6.0-rc2srclib_jsonjson_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
MsgTile:%s
MsgContent:%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

文章结束给大家分享下程序员的一些笑话语录: 程序员的愿望
  有一天一个程序员见到了上帝.上帝: 小伙子,我可以满足你一个愿望.程序员: 我希望中国国家队能再次打进世界杯.
  上帝: 这个啊!这个不好办啊,你还说下一个吧!
  程序员: 那好!我的下一个愿望是每天都能休息6个小时以上.
  上帝: 还是让中国国家打进世界杯.

--------------------------------- 原创文章 By
序列化和对象
---------------------------------

免责声明:文章转载自《序列化对象C++对象的JSON序列化与反序列化探索》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Kafka win10下启动JSON.stringify 后数据丢失下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

基于Memcached的tomcat集群session共享所用的jar及多个tomcat各种序列化策略配置

原文:http://www.cnblogs.com/interdrp/p/4096466.html 多个tomcat各种序列化策略配置如下:一、java默认序列化tomcat配置conf/context.xml添加<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManag...

phpredis中incr以及decr等自增命令出现的问题

在做项目中使用redis的incr以及hincrby自增时,出现自增失败,set之后的数据,无法自增,当redis中不存在该key时,直接用incr是成功的。查找了原因,是因为phpredis初始化的时候,设置了php序列化,即: $redis->setOption( Redis::OPT_SERIALIZER, Redis::SERIALIZER_...

nodejs 的序列化与反序列化

1.序列化 stringify函数的作用就是序列化对象,也就是说将对象类型转换成一个字符串类型(默认的分割符("&")和分配符("=")),先介绍它的基本用法,在下一节里我们将学习如何替换默认分配符,下面我们就通过以下例子来清楚的认识一下吧! 例1:querystring.stringify("对象") var querystring= requi...

C# XML序列化/反序列化类XmlSerializer使用示例

using System; using System.IO; using System.Text; using System.Xml; using System.Xml.Serialization; namespace ConsoleApplication1 { class Program { static void Ma...

关于大小型项目如何最大限度提高WebAPi性能

前言 WebAPi作为接口请求的一种服务,当我们请求该服务时我们目标是需要快速获取该服务的数据响应,这种情况在大型项目中尤为常见,此时迫切需要提高WebAPi的响应机制,当然也少不了前端需要作出的努力,这里我们只讲述在大小型项目中如何利用后台逻辑尽可能最大限度提高WebAPi性能,我们从以下几个方面来进行阐述。 性能提升一:JSON序列化器(Jil) 在....

Web_php_unserialize(序列化与反序列化)

题目 题目是这样的 很明显是一道 PHP 反序列化的题目 , 直接来看题目给出的流程 首先判断当前是否存在 GET 参数 " var " , 若存在则对其进行 Base64 解码后存入 $var 变量 . 若不存在则输出当前页面源码 对 $var 进行一个正则过滤 , 若通过正则过滤 , 则对其进行反序列化操作 , 否则响应提示信息 . 题目中给出一...