近期项目用到了json规范来实现数据传递,但是由于c++没有反射功能,在使用json的时候,无法做到定义class,则能自动生成对象转json字符串和json字符串反序列化为对象的功能。每次新增对象,或者修改字段,都必须手动修改c++代码,这样的搬砖非常苦恼。顾想设计一个自动生成对象和json代码的工具。思路如下图:
使用界面操作,然后生成json文件,为代码生成工具生成代码提供依据。
一、项目管理,右键菜单增加项目
二、右键菜单为项目增加对象
三、为对象增加字段
四、点击【生成代码】按钮,生成c++代码
头文件
#ifndef __TESTPROJECT__H
#define __TESTPROJECT__H
#ifdef WIN32
#ifndef TESTPROJECT_DEFINE_EXPORT
#define TESTPROJECT_EXPORT __declspec(dllimport)
#else
#define TESTPROJECT_EXPORT __declspec(dllexport)
#endif
#else
#define TESTPROJECT_EXPORT
#endif
#include "aijsonconvertbase.h"
#include <map>
#include <string>
namespace testproject
{
const int PROJECT_VERSION = 1;
const std::string PROJECT_NAME = "testproject";
/* 测试对象 .*/
class TESTPROJECT_EXPORT testclass : public AIJsonConvertBase
{
public:
/* 测试字段 .*/
std::string testfield1 = "";
/* 测试字段2 .*/
std::map<std::string,std::string> testfield2;
/* 测试字段3 .*/
int testfield3 = 1;
public:
testclass();
virtual ~testclass();
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 //__TESTPROJECT__H
源码文件
#ifdef WIN32
#pragma warning(disable:4251)
#pragma warning(disable:4244)
#pragma warning(disable:4275)
#pragma warning(disable:4018)
#pragma warning(disable:4019)
#pragma warning(disable:4819)
#pragma warning(disable:4217)
#endif //WIN32
#ifndef TESTPROJECT_DEFINE_EXPORT
#define TESTPROJECT_DEFINE_EXPORT
#endif
#include "aiautovaluemanager.h"
#include "rapidjsonassert.h"
#include "testproject.h"
testproject::testclass::testclass()
{
AIAutovalueManager::instance()->GetAutoValue("testproject", "testclass", "testfield1", testfield1);
AIAutovalueManager::instance()->GetAutoValue("testproject", "testclass", "testfield3", testfield3);
}
testproject::testclass::~testclass()
{
this->Clear();
testfield2.clear();
}
bool testproject::testclass::ObjectFromMap(const std::map<std::string, std::string> &dataInt)
{
this->Clear();
AImapDataManager::GetDataFromMap("testfield1", testfield1, dataInt);
AImapDataManager::GetDataFromMap("testfield2", testfield2, dataInt);
AImapDataManager::GetDataFromMap("testfield3", testfield3, dataInt);
return true;
}
bool testproject::testclass::ObjectFromJson(const std::string &jsonInt)
{
rapidjson::Document *pDoc = new rapidjson::Document;
if (NULL == pDoc)
{
return false;
}
pDoc->Parse<0>(jsonInt.c_str());
if (pDoc->HasParseError())
{
delete pDoc;
pDoc = NULL;
return false;
}
else
{
this->ObjectFromJsonElement((void*)pDoc);
}
if (NULL != pDoc)
{
delete pDoc;
pDoc = NULL;
}
return true;
}
bool testproject::testclass::ObjectFromJsonElement(void* pElementIn)
{
if (NULL != pElementIn)
{
rapidjson::Value *pElement = (rapidjson::Value *)pElementIn;
rapidjson::Value &t_element = *pElement;
this->Clear();
RAPIDJSON_GET_STRING_BYNAME(testfield1, "testfield1", t_element);
RAPIDJSON_GET_STRINGMAP_BYNAME(testfield2, "testfield2", t_element);
RAPIDJSON_GET_INT_BYNAME(testfield3, "testfield3", t_element);
return true;
}
return false;
}
bool testproject::testclass::ObjectToJson(std::string &jsonOut, std::map<std::string, bool> *pFileds/* = NULL*/)
{
rapidjson::Document Doc;
rapidjson::Value tElem(rapidjson::kObjectType);
if (ObjectToJsonElement(&Doc, &tElem, pFileds))
{
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
tElem.Accept(writer);
jsonOut = buffer.GetString();
return true;
}
return false;
}
bool testproject::testclass::ObjectToJsonElement(void *pDoc, void *pElement, std::map<std::string, bool> *pFileds/* = NULL*/)
{
if (NULL != pDoc && NULL != pElement)
{
rapidjson::Document *t_pDoc = (rapidjson::Document *)pDoc;
rapidjson::Value *t_pElement = (rapidjson::Value *)pElement;
rapidjson::Document &_doc = *t_pDoc;
rapidjson::Value &_element = *t_pElement;
RAPIDJSON_ADDMEMBER_STRING(_element, "testfield1", testfield1, _doc, pFileds);
RAPIDJSON_ADDMEMBER_STRINGMap(_element, "testfield2", testfield2, _doc, pFileds);
RAPIDJSON_ADDMEMBER(_element, "testfield3", testfield3, _doc, pFileds);
return true;
}
return false;
}
bool testproject::testclass::ObjectToMap(std::map<std::string, std::string> &dataOut)
{
AImapDataManager::SetMapData("testfield1", testfield1, dataOut);
AImapDataManager::SetMapData("testfield2", testfield2, dataOut);
AImapDataManager::SetMapData("testfield3", testfield3, dataOut);
return true;
}
std::string testproject::testclass::GetObjectName()
{
return "testclass";
}
AIJsonConvertBase* testproject::testclass::NewObject()
{
return new testclass();
}
AIJsonConvertBase* testproject::testclass::Clone()
{
testclass*newobj = new testclass();
if(NULL == newobj){
return NULL;
}
newobj->Copy(this);
return newobj;
}
bool testproject::testclass::Copy(AIJsonConvertBase* pObject)
{
if(NULL == pObject){
return false;
}
testclass *t_obj = dynamic_cast<testclass*>(pObject);
if(NULL == t_obj){
return false;
}
testfield1=t_obj->testfield1;
testfield2=t_obj->testfield2;
testfield3=t_obj->testfield3;
return true;
}
bool testproject::testclass::Clear()
{
testfield1 = "";
testfield2.clear();
testfield3 = -1;
return true;
}
五、代码生成工具下载地址
代码生成工具