近期项目用到了json规范来实现数据传递,但是由于c++没有反射功能,在使用json的时候,无法做到定义class,则能自动生成对象转json字符串和json字符串反序列化为对象的功能。每次新增对象,或者修改字段,都必须手动修改c++代码,这样的搬砖非常苦恼。顾想设计一个自动生成对象和json代码的工具。思路如下图:
一、设计c++对象和json相互转换的基类接口:
通过该基类,可以实现对象、map、json之间的相互转换。在模块交互的数据接口,则可以简单设计为
int DoData(const std::string &key,const std::string &value);
就可以实现面向对象的数据传输。
发送方通过ObjectToMap、ObjectToJson方法,生成中间数据。接收方根据key,通过工厂方法创建一个对象,然后再使用ObjectFromMap、ObjectFromJson方法,反序列化为对象。
1、智能对象基类接口
#ifndef __AICONVERTBASE_H
#define __AICONVERTBASE_H
#include <string>
#include <map>
class AIJsonConvertBase
{
public:
virtual ~AIJsonConvertBase(){}
public:
/// <summary>
/// 对象map字典解析.
/// </summary>
/// <param name="dataInt">map字典.</param>
/// <returns>true/flase.</returns>
virtual bool ObjectFromMap(const std::map<std::string,std::string> &dataInt){ return false; }
/// <summary>
/// 对象从JSON字符串解析.
/// </summary>
/// <param name="jsonInt">JSON格式字符串.</param>
/// <returns>true/flase.</returns>
virtual bool ObjectFromJson(const std::string &jsonInt){ return false; }
/// <summary>
/// 对象从JSON对象(rapidjson::Value)解析.
/// </summary>
/// <param name="pElementIn">JSON对象:rapidjson::Value.</param>
/// <returns>true/flase.</returns>
virtual bool ObjectFromJsonElement(void* pElementIn){ return false; }
/// <summary>
/// 对象转换为map字典 .
/// </summary>
/// <param name="dataOut">返回的map字典.</param>
/// <param name="pFileds">如果pFileds==NULL表示生成整个对象的json,否则生成pFileds里面value=true的key字段的json.(std::map<字段名称,生成标识:false表示不生成,true表示生成>)</param>
/// <returns>true/flase.</returns>
virtual bool ObjectToMap(std::map<std::string, std::string> &dataOut){ return false; }
/// <summary>
/// 对象转换为JSON字符串.
/// </summary>
/// <param name="jsonOut">返回的json字符串.</param>
/// <param name="pFileds">如果pFileds==NULL表示生成整个对象的json,否则生成pFileds里面value=true的key字段的json.(std::map<字段名称,生成标识:false表示不生成,true表示生成>)</param>
/// <returns>true/flase.</returns>
virtual bool ObjectToJson(std::string &jsonOut,std::map<std::string,bool> *pFileds = NULL){ return false; }
/// <summary>
/// 对象转换为JSON对象.
/// </summary>
/// <param name="pDoc">JSON doc:rapidjson::Document.</param>
/// <param name="pElement">JSON对象:rapidjson::Value.</param>
/// <param name="pFileds">如果pFileds==NULL表示生成整个对象的json,否则生成pFileds里面value=true的key字段的json.(std::map<字段名称,生成标识:false表示不生成\true表示生成>)</param>
/// <returns>true/flase.</returns>
virtual bool ObjectToJsonElement(void *pDoc, void *pElement, std::map<std::string, bool> *pFileds = NULL){ return false; }
/// <summary>
/// 获取类名.
/// </summary>
/// <returns>获取类名字符串.</returns>
virtual std::string GetObjectName(){ return "AIJsonConvertBase"; }
/// <summary>
/// 创建自身对象.
/// </summary>
/// <returns>对象基类指针.</returns>
virtual AIJsonConvertBase* NewObject(){ return NULL; }
/// <summary>
/// 克隆自身对象.
/// </summary>
/// <returns>对象基类指针.</returns>
virtual AIJsonConvertBase* Clone(){ return new AIJsonConvertBase; }
/// <summary>
/// 深拷贝对象.
/// </summary>
/// <param name="pDoc">JSON doc:rapidjson::Document.</param>
/// <returns>true/flase.</returns>
virtual bool Copy(AIJsonConvertBase* pObject){ return true; }
/// <summary>
/// 清理对象.
/// </summary>
/// <returns>true/flase .</returns>
virtual bool Clear(){ return true; }
};
#endif
2、创建智能对象的工厂接口
#ifndef __AICREATEAIOBJECT_H__
#define __AICREATEAIOBJECT_H__
#include "aijsonconvertbase.h"
#ifdef WIN32
#ifndef AICREATEAIOBJECT_DEFINE_EXPORT
#define AICREATEAIOBJECT_EXPORT __declspec(dllimport)
#else
#define AICREATEAIOBJECT_EXPORT __declspec(dllexport)
#endif
#else
#define AICREATEAIOBJECT_EXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
AICREATEAIOBJECT_EXPORT AIJsonConvertBase* CreateAIObject(const char* namespacestr, const char* classname);
AICREATEAIOBJECT_EXPORT void ReleaseAIObject(AIJsonConvertBase* &aiobject);
#ifdef __cplusplus
}
#endif
#endif//__AICREATEAIOBJECT_H__
二、生成代码样例
1、头文件
#ifndef __AIJSONUTILS__H
#define __AIJSONUTILS__H
#ifdef WIN32
#ifndef AIJSONUTILS_DEFINE_EXPORT
#define AIJSONUTILS_EXPORT __declspec(dllimport)
#else
#define AIJSONUTILS_EXPORT __declspec(dllexport)
#endif
#else
#define AIJSONUTILS_EXPORT
#endif
#include "aijsonconvertbase.h"
#include <map>
#include <string>
#include <vector>
namespace aijsonutils
{
/* 结果数据 .*/
class AIJSONUTILS_EXPORT df_reslutdata : public AIJsonConvertBase
{
public:
/* 结果 .*/
std::string result = "";
/* 信息描述 .*/
std::string info = "";
/* 数据 .*/
std::string data = "";
public:
df_reslutdata();
virtual ~df_reslutdata();
public:
/// Functional methods please refer to the base class(AIJsonConvertBase) description
bool ObjectFromJson(const std::string &jsonInt);
bool ObjectFromMap(const std::map<std::string,std::string> &dataInt);
bool ObjectToJson(std::string &jsonOut,std::map<std::string, bool> *pFileds = NULL);
bool ObjectToMap(std::map<std::string, std::string> &dataOut);
std::string GetObjectName();
public:
bool ObjectFromJsonElement(void* pElementIn);
bool ObjectToJsonElement(void *pDoc, void *pElement, std::map<std::string, bool> *pFileds = NULL);
AIJsonConvertBase* NewObject();
AIJsonConvertBase* Clone();
bool Copy(AIJsonConvertBase* pObject);
bool Clear();
};
}
#endif //__AIJSONUTILS__H
三、使用样例
#include "aijsonutils.h"//智能对象定义
#include "aicreateaiobject.h"//工厂接口
#include <iostream>
using namespace aijsonutils;
int DoData(const std::string &namespacestr, const std::string &classname, const std::string &value)
{
AIJsonConvertBase* myboj = CreateAIObject(namespacestr.c_str(), classname.c_str());
if (NULL != myboj)
{
if (myboj->ObjectFromJson(value))//json字符串转对象
{
aijsonutils::df_reslutdata* myResult = dynamic_cast<aijsonutils::df_reslutdata*>(myboj);
if (NULL != myResult)
{
std::cout << myResult->result << std::endl;
std::cout << myResult->data << std::endl;
std::cout << myResult->info << std::endl;
}
}
ReleaseAIObject(myboj);
}
}
int main()
{
aijsonutils::df_reslutdata myResultData;
myResultData.result = "1";
myResultData.data = "testdata";
myResultData.info = "testinfo";
std::string value;
if (myResultData.ObjectToJson(value))//对象转json字符串
{
return DoData("aijsonutils", "df_reslutdata", value);
}
return 0;
}
四、代码生成工具下载地址
代码生成工具