上一篇文章已经简单介绍了json2jsoncpp的基本功能以及下载地址(已经更新linux/mac/win)。本篇将介绍json2jsoncpp的一个高级功能(类似RPC的功能)
为了方便描述,我在这里以及以后将json2jsoncpp简称为j2jc
上一篇文章的介绍,其实j2jc的功能实际上就是吧一个json数据格式文档转换为一个或多个类,所以只需要少许代码便可以实现rpc功能了,其中代码中要包含:
1:过程名(类名)
2:解析json并且调用相对于的过程或者是生成相对应的对象
这样就实现了一个无返回值的rpc
其实就是代码要实现 拿到一个json数据就自动生成一个相对应的类对象
这里j2jc已经帮你实现了
你只需要先生成一个h头文件:
json2jsoncpp test.json test.h j
请不要少打了这个j
test.json
{ //先给你的json数据包格式起个名字叫做rpc1 "rpc1" : { "age":16,//年龄 "hp":99,//血 "mp":88//魔法 } }
自动会生成test.h
//charset: #ifndef test_h #define test_h #include <vector> #include <string> #include "json/json.h" #include "json2jsoncpp.h" ////////////////////////////////////////////////////////////////////////// //先给你的json数据包格式起个名字叫做rpc1 class rpc1:public json2jsoncpp { private: virtual bool decodesuccess(){return true;} static string2object * NEW() { return new rpc1; } public: static bool REG(newobjfun fun=0) { if(fun)return string2object::REG("rpc1",fun); else return string2object::REG("rpc1",NEW); } static bool UNREG() { return string2object::UNREG("rpc1"); } rpc1() { age = 16; hp = 99; mp = 88; } void reset() { age = 16; hp = 99; mp = 88; } bool decode(std::string json) { Json::Reader jr; Json::Value jv; if(!jr.parse(json,jv)) { printf("parse err!\n"); return false; } return decode(jv); } bool decode(Json::Value & _jv,int dontCheckPacketName=0) { Json::Value jv; if( dontCheckPacketName ) { jv=_jv; } else { if( Json::objectValue!=_jv["rpc1"].type() )return false; jv=_jv["rpc1"]; } if( jv["age"].type()==Json::intValue || jv["age"].type()==Json::uintValue ) age = jv["age"].asInt64(); if( jv["hp"].type()==Json::intValue || jv["hp"].type()==Json::uintValue ) hp = jv["hp"].asInt64(); if( jv["mp"].type()==Json::intValue || jv["mp"].type()==Json::uintValue ) mp = jv["mp"].asInt64(); return decodesuccess(); } std::string encode2string(int dontMakePacketName=0) { return encode(dontMakePacketName).toStyledString(); } Json::Value encode(int dontMakePacketName=0) { Json::Value root; root["age"]=Json::Value(age); root["hp"]=Json::Value(hp); root["mp"]=Json::Value(mp); if(dontMakePacketName) { return root; } else { Json::Value retval; retval["rpc1"]=root; return retval; } } long long age; //年龄 long long hp; //血 long long mp; //魔法 } ; ////////////////////////////////////////////////////////////////////////// #endif //test_h
写入demo.cpp来测试一下:
// demo.cpp : // #include "demo.h" #include "json2jsoncpp.h" #ifdef _MSC_VER #pragma comment(lib,"json_vc71_libmt.lib") #pragma warning(disable:4996) #endif class G1:public rpc1 { public: G1() { printf("G1();\n"); } ~G1() { printf("~G1();\n"); } bool decodesuccess() { printf("G1::decodesuccess()hp=%d;\n",this->hp);//当解析完毕保存好内容后,就调用decodesuccess return true;//返回false就是取消这次生成的对象,内部会自动销毁他 } }; int main(int argc, char* argv[]) { json2jsoncpp::INIT();//初始化一下库 json2jsoncpp::REG<G1>();//向json //先生成一个json数据拿来测试 rpc1 aa; aa.hp=100; printf("%s\n",aa.encode2string().c_str()); printf("///////////////////////////////////////\n"); //把一个json数据放入库解析并且创建一个对象,如果创建成功后会调用对象的decodesuccess json2jsoncpp::decode(aa.encode2string()); json2jsoncpp::UNREG<G1>();//反注册G1 json2jsoncpp::UNINIT();//销毁库 return 0; }
执行结果:
可以看到,j2jc生成的对象encode出来的数据带着类名 “rpc1” 这样就满足了刚才说的第一点 包含了一个类名,这样解析方才能得知这个json数据是属于哪个类的,然后再生成对象出来
当json数据放入json2jsoncpp::decode后, json2jsoncpp通过刚才注册过的类信息自动生成一个相对应的类来,并且调用decodesuccess来通知执行后面的逻辑,这时候你就可以在decodesuccess来执行相关的逻辑编码了
这样的好处就是接收解码和逻辑代码分离,比较清晰
刚才提到代码中用到的两个头文件和程序在这里:
http://pan.baidu.com/share/link?shareid=309238&uk=3711199009
好了,先写到这里,下一篇我将介绍j2jc实现这些功能的一些原理(代码分析)