当前位置: 首页 > news >正文

Jsonlizer,一个把C++各类数据转成 Json 结构体的玩意儿

        这段时间突发奇想,觉得可以弄一个Json和C++各种数据类型互转的工具,因为Json在进行数据储存的时候,有一些先天的优势,传统的C++的序列化方式是将数据序列化到流数据里面,而流数据是典型的串行结构(或则说是一维结构),因此,流数据对数据的位置特别的敏感,一旦序列化的元素有调整,就会导致原来存储的流数据完全失效。这一点在游戏开发时非常的麻烦,我们不得不将各个接口进行拆分,让接口对应其独自的流数据,做到局部的隔离。但是这个办法也不是万能,因为,一旦接口内某些元素顺序因为开始时过于简单而并没有做拆分时,隐藏的风险种子就种下了。随着时间推移,一旦需要更改这些元素时,就会发现被锁死了手脚!

        Json具有结构化的特征,涵盖了原型,数组,对象等数据类型,用来做存储是非常理想的,如果项目中存储的数据用Json存储,然后再序列化到二进制流数据内,这样似乎就结合了两者的优点,结合了速度和可扩展性。而我自己写的CJson类本身就是可以序列化到流数据的。而且从流数据恢复的速度远比解析Json字符串的速度快几倍,那么现在欠缺的就是如何将C++数据转换成CJson类。

        思考了一段时间,我意识到 Jsonlizer 和 Serializer 有本质的区别,一个是构建层次结构,一个是构建一维结构,我本来想尽可能的复用Serializer的代码,但我意识到,这是不可能的。我能利用的,可能仅仅是一部分最基本的,被称为 trait 模板代码。

        而想复用Serialize函数的想法是不可能的。毕竟一个是结构化的数据,一个是一维数据。于是我改变了策略,重新构造了Jsonlizer。首先要做的是重写整个Jsonlizer的模板代码。这部分代码非常的关键,就是用于识别C++的各类数据。

这几个文件的代码如下:

#ifndef TAGPJSONLIZERRIMITIVE_H
#define TAGPJSONLIZERRIMITIVE_H
//Begin section for file tagJsonPrimitive.h
//TODO: Add definitions that you want preserved
//End section for file tagJsonPrimitive.hnamespace atom
{//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template <class A, class T, bool save>struct tagJsonPrimitive{//Begin section for si::tagJsonPrimitive//TODO: Add attributes that you want preserved//End section for si::tagJsonPrimitivepublic://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline static void Invoke(A & node, T & t){//TODO Auto-generated method stubnode.Bind( t );}};  //end struct tagJsonPrimitive} // end namespace atom#endif

原型非常简单,没什么好说的。

#ifndef TAGJSONLIZERINVALID_H
#define TAGJSONLIZERINVALID_H
//Begin section for file tagJsonInvalid.h
//TODO: Add definitions that you want preserved
//End section for file tagJsonInvalid.hnamespace atom
{//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template <class A, class T, bool save>struct tagJsonInvalid{//Begin section for si::tagJsonInvalid//TODO: Add attributes that you want preserved//End section for si::tagJsonInvalidpublic://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline static void Invoke(A & n, T & t){UNREFERENCED_PARAMETER(n);UNREFERENCED_PARAMETER(t);//TODO Auto-generated method stubprintf( "Jsonlization NOT support these keyword: mutable\n" );}};  //end struct tagJsonInvalid} // end namespace atom#endif

 不支持的类型就是输出提示。

#ifndef TAGJSONLIZERARRAY_H
#define TAGJSONLIZERARRAY_H
//Begin section for file tagJsonArray.h
//TODO: Add definitions that you want preserved
//End section for file tagJsonArray.h
#include "../../../serialization/trait/array_trait.h"namespace atom
{//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template <class A, class T, bool save>struct tagJsonArray{//Begin section for si::tagJsonArray//TODO: Add attributes that you want preserved//End section for si::tagJsonArraypublic://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline static void Invoke(A & jr, T & t){//TODO Auto-generated method stub// 读取或写入数组的长度;U32 bound = static_cast<U32>( array_trait<T>::bound );U32 limit = bound;CJson node = jr.GetCurrentNode();if( save == false ) {bound = static_cast<U32>( node.Length() );}// 确认数组的长度是否越界;bound = atom_min( bound, limit );// 读取或写入数组的元素;for( size_t i = 0; i < bound; ++ i ){CJson child( true );if( save == false ) {child = node[i];}jr.Push( child );jr.Bind( t[i] );jr.Pop();if( save ) {node.Push( child );}}}};  //end struct tagJsonArray} // end namespace atom#endif

        数组开始有点东西了,其中能看到 Jsonlizer 有几个函数:Push,Pop,GetCurrentNode。这几个函数其实就是维护一个节点堆栈,堆栈内放入的是被操作的节点列表。顶部的节点就是最新需要被操作的节点。

#ifndef TAGJSONLIZERCLASS_H
#define TAGJSONLIZERCLASS_H
//Begin section for file tagJsonClass.h
//TODO: Add definitions that you want preserved
//End section for file tagJsonClass.h// 为序列化类而特别准备的缺省模板函数。
template<class A, class T>
inline void Jsonlize(A & jr, T & t, bool save)
{t.Jsonlize( jr, save );
}namespace atom
{//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template <class A, class T, bool save>struct tagJsonClass{//Begin section for si::tagJsonClass//TODO: Add attributes that you want preserved//End section for si::tagJsonClasspublic://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline static void Invoke(A & jr, T & t){//TODO Auto-generated method stubJsonlize( jr, t, save );}};  //end struct tagJsonClass} // end namespace atom#endif

 类的代码其实不复杂,因为类的代码需要用户自己完成。

#ifndef TAGJSONLIZER_H
#define TAGJSONLIZER_H
//Begin section for file tagJsonlizer.h
//TODO: Add definitions that you want preserved
//End section for file tagJsonlizer.h#include "../../../serialization/trait/is_primitive.h"
#include "../../../serialization/trait/is_array.h"
#include "../../../serialization/trait/is_class.h"
#include "../../../serialization/trait/is_pointer.h"
#include "../../../serialization/trait/if_else.h"
#include "../../../serialization/trait/degradation_trait.h"
#include "tagJsonPrimitive.h"
#include "tagJsonArray.h" 
#include "tagJsonClass.h"
#include "tagJsonInvalid.h"namespace atom
{//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template <class A, class T, bool B>struct tagJsonlizer{//Begin section for si::tagJsonlizer//TODO: Add attributes that you want preserved//End section for si::tagJsonlizerpublic://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline static void Jsonlize(A & json, T & data){//TODO Auto-generated method stubtypedef typename degradation_trait<T>::type C;typedef typenameif_else<is_array<C>::value,tagJsonArray<A, C, B>, typenameif_else<is_class<C>::value, tagJsonClass<A, C, B>, typenameif_else<is_primitive<C>::value,tagJsonPrimitive<A, C, B>,tagJsonInvalid  <A, C, B>>::type >::type >::type Invoker;Invoker::Invoke( json, type_cast(data) );}};  //end struct tagJsonlizer} // end namespace atom#endif

这个就是Jsonlizer模板的入口了,接下来就是导入,导出类的代码。

#ifndef CJSONIMPORTER_H
#define CJSONIMPORTER_H
//Begin section for file CJsonImporter.h
//TODO: Add definitions that you want preserved
//End section for file CJsonImporter.h
#include "../../../Common.h"
#include "../../../interface/IEmbedInterface.h"
#include "../../../interface/IInterface.h"
#include "../../../interface/IJsonlizerRoot.h"
#include "../../../enumeration/INTERFACE_ID.h"
#include "../../../os/character/CCharset.h"
#include "../../stl/a_string.h"
#include "../../stl/a_wstring.h"
#include "../../hex/hex.h"
#include "../../tool/CInterface.h"
#include "tagJsonlizer.h"namespace atom
{//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"class CJsonImporter : public IEmbedInterface{//Begin section for atom::CJsonImporter//TODO: Add attributes that you want preserved//End section for atom::CJsonImporterprivate://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"IInterface * nest;#ifdef _SHIPPING_//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"IReferencedInterface * cast;#endifpublic://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"CJsonImporter(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual ~CJsonImporter(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual int IncRef(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual int DecRef(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual int GetRef(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual IInterface * QueryInterface(U32 iid); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual void SetNest(IInterface * nest); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline CJson GetCurrentNode(){// TODO Auto-generated method stubCJson result;CInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ) {result = root -> GetCurrentNode();}return result;}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Push(CJson & node){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ) {root -> Push( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Pop(){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ) {root -> Pop();}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(bool & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<bool>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(char & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<U08>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(I08 & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<I08>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(I16 & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<I16>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(I32 & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<I32>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(I64 & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<I64>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(U08 & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<U08>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(U16 & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<U16>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(U32 & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<U32>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(U64 & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<U64>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(float & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<float>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(double & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<double>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(a_string & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();value = static_cast<a_string>( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(a_wstring & value){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();a_string text = node;CCharset charset( text.c_str() );value = charset.FromUtf8.ToUnicode;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(void * buffer, U64 length){// TODO Auto-generated method stubif( buffer && length ){CInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();a_string text = node;FromHex( text, buffer, length );}}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template<class T>inline void Bind(T & value){//TODO Auto-generated method stubtagJsonlizer<CJsonImporter, T, false>::Jsonlize( *this, value );}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template<class T>inline void Bind(const char * name, T & value){//TODO Auto-generated method stubif( name ){CInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node  = root -> GetCurrentNode();CJson child = node[name];root -> Push( child );Bind( value );root -> Pop();}}}};  //end class CJsonImporter} //end namespace atom#endif

#ifndef CJSONEXPORTER_H
#define CJSONEXPORTER_H
//Begin section for file CJsonExporter.h
//TODO: Add definitions that you want preserved
//End section for file CJsonExporter.h
#include "../../../Common.h"
#include "../../../interface/IEmbedInterface.h"
#include "../../../interface/IInterface.h"
#include "../../../interface/IJsonlizerRoot.h"
#include "../../../enumeration/INTERFACE_ID.h"
#include "../../../os/character/CCharset.h"
#include "../../stl/a_string.h"
#include "../../stl/a_wstring.h"
#include "../../hex/hex.h"
#include "../../tool/CInterface.h"
#include "tagJsonlizer.h"namespace atom
{//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"class CJsonExporter : public IEmbedInterface{//Begin section for atom::CJsonExporter//TODO: Add attributes that you want preserved//End section for atom::CJsonExporterprivate://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"IInterface * nest;#ifdef _SHIPPING_//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"IReferencedInterface * cast;#endifpublic://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"CJsonExporter(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual ~CJsonExporter(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual int IncRef(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual int DecRef(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual int GetRef(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual IInterface * QueryInterface(U32 iid); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual void SetNest(IInterface * nest); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline CJson GetCurrentNode(){// TODO Auto-generated method stubCJson result;CInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ) {result = root -> GetCurrentNode();}return result;}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Push(CJson & node){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ) {root -> Push( node );}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Pop(){// TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ) {root -> Pop();}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(bool & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(char & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(I08 & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(I16 & value) {//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(I32 & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(I64 & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(U08 & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(U16 & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(U32 & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(U64 & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(float & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(double & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(const char * value) {//TODO Auto-generated method stubif( value ){CInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value;}}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(const wchar_t * value){//TODO Auto-generated method stubif( value ){CInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();CCharset charset( value );a_string text = charset.ToUtf8;node = text.c_str();}}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(a_string & value) {//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();node = value.c_str();}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(a_wstring & value){//TODO Auto-generated method stubCInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node = root -> GetCurrentNode();CCharset charset( value.c_str() );a_string text = charset.ToUtf8;node = text.c_str();}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Bind(void * buffer, U64 length){//TODO Auto-generated method stubif( buffer && length ){CInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){a_string text = ToHex( buffer, length );CJson node = root -> GetCurrentNode();node = text.c_str();}}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template<class T>inline void Bind(T & value){//TODO Auto-generated method stubtagJsonlizer<CJsonExporter, T, true>::Jsonlize( * this, value );}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template<class T>inline void Bind(const T & value){//TODO Auto-generated method stubBind( const_cast<T &>(value) );}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template<class T>inline void Bind(const char * name, T & value){//TODO Auto-generated method stubif( name ){CInterface<IJsonlizerRoot> root;if( root.Mount(this, IID_JSONLIZER_ROOT) ){CJson node  = root -> GetCurrentNode();CJson child = node[name];root -> Push( child );Bind( value );root -> Pop();}}}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template<class T>inline void Bind(const char * name, const T & value){//TODO Auto-generated method stubBind( name, const_cast<T &>(value) );}};  //end class CJsonExporter} //end namespace atom#endif

导入导出的类有一个特殊的函数:

inline void Bind(const char * name, T & value)

这个函数带了一个name的参数,其实就是针对类的成员变量而设的。

#ifndef CJSONLIZER_H
#define CJSONLIZER_H
//Begin section for file CJsonlizer.h
//TODO: Add definitions that you want preserved
//End section for file CJsonlizer.h
#include "../../../Common.h"
#include "CJsonExporter.h"
#include "CJsonImporter.h"
#include "CJsonlizerRoot.h"
#include "../CJson.h"inline const char * last_dot(const char * value)
{const char * result(value);if( value ) {for( ;; ++ value ){if( *value == 0 ) break;if( *value == '.' ) {result = value + 1;}}}    return result;
}#define JKV(V) make_pair(a_string(#V), V)
#define JBD(A,V)  A.Bind(last_dot(#V), V)namespace atom
{//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"class CJsonlizer : public IInterface{//Begin section for atom::CJsonlizer//TODO: Add attributes that you want preserved//End section for atom::CJsonlizerprivate://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"CJsonExporter exporter;//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"CJsonImporter importer;//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"CJsonlizerRoot root;public://@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"CJsonlizer(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual ~CJsonlizer(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"virtual IInterface * QueryInterface(U32 iid); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool Assign(CJson & data); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"bool Obtain(CJson & data); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"void Clear(); //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline CJson GetCurrentNode(){//TODO Auto-generated method stubroot.GetCurrentNode();}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Push(CJson & node){//TODO Auto-generated method stubroot.Push( node );}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"inline void Pop(){//TODO Auto-generated method stubroot.Pop();}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template<class T>inline CJsonlizer & operator <<(const T & value){//TODO Auto-generated method stubexporter.Bind( value );return( * this );}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template<class T>inline CJsonlizer & operator <<(const pair<a_string, T> & value){//TODO Auto-generated method stubexporter.Bind( value.first.c_str(), value.second );return( * this );}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template<class T>inline CJsonlizer & operator >>(T & value){//TODO Auto-generated method stubimporter.Bind( value );return( * this );}//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"template<class T>inline CJsonlizer & operator >>(pair<a_string, T> & value){//TODO Auto-generated method stubimporter.Bind( value.first.c_str(), value.second );return( * this );}};  //end class CJsonlizer} //end namespace atom#endif

        最后就是最终的绑定接口了,接下来我展示一个简单的例子:

struct tagTest
{U32 index;a_string name;tagTest():index(0) {}~tagTest() {}
};struct tagTest2
{U32 index;tagTest value[4];tagTest2():index(0) {}~tagTest2() {}
};template<class A>
inline void Jsonlize(A & jr, tagTest & t, bool save)
{JBD( jr, t.index );JBD( jr, t.name );
}template<class A>
inline void Jsonlize(A & jr, tagTest2 & t, bool save)
{JBD( jr, t.index );JBD( jr, t.value );
}

准备了两个类,这两个类有聚合关系。然后我初始化这两个类,然后用Jsonizer将这个类导出成Json数据结构。

		tagTest2 in, out;in.index = 1;in.value[0].index = 101;in.value[0].name  = "101";in.value[1].index = 102;in.value[1].name  = "102";in.value[2].index = 103;in.value[2].name  = "103";in.value[3].index = 104;in.value[3].name  = "104";CJsonlizer jr;jr << in;CJson json;jr.Obtain( json );a_string value = json.Stringify();printf( "%s\n", value.c_str() );

运行的结果如下:

其实并不困难。大家也可以试试,其中 trait 的那些代码可以去看看boost的序列化相关的代码。

相关文章:

Jsonlizer,一个把C++各类数据转成 Json 结构体的玩意儿

这段时间突发奇想&#xff0c;觉得可以弄一个Json和C各种数据类型互转的工具&#xff0c;因为Json在进行数据储存的时候&#xff0c;有一些先天的优势&#xff0c;传统的C的序列化方式是将数据序列化到流数据里面&#xff0c;而流数据是典型的串行结构&#xff08;或则说是一维…...

Qt仿音乐播放器:设置窗口、部件属性

// 设置窗口标志 this->setWindowFlag(Qt::FramelessWindowHint); //此设置将窗口设置成无边框模式//设置窗口背景透明 this->setAttribute(Qt::WA_TranslucentBackground,true); attribute&#xff1a;属性 Translucent&#xff1a;半透明 Qt::WA_TranslucentBackgro…...

使用 .NET 6 或 .NET 8 上传大文件

如果您正在使用 .NET 6&#xff0c;并且它拒绝上传大文件&#xff0c;那么本文适合您。 我分享了一些处理大文件时需要牢记的建议&#xff0c;以及如何根据我们的需求配置我们的服务&#xff0c;并提供无限制的服务。 本文与 https://blog.csdn.net/hefeng_aspnet/arti…...

基于特征工程(pca分析)、小波去噪以及数据增强,同时采用基于注意力机制的BiLSTM、随机森林、ARIMA模型进行序列数据预测

本文采用特征工程&#xff08;pca分析&#xff09;、小波去噪以及数据增强&#xff0c;同时采用基于注意力机制的BiLSTM、随机森林、ARIMA模型进行序列数据预测 基于BILSTM&#xff08;双向长短期记忆网络&#xff09;、随机森林回归和ARIMA&#xff08;自回归积分滑动平均&am…...

攻防世界 PHP2

开启场景 访问 /index.php&#xff0c;页面无变化 访问 /index.phps index.php 和 index.phps 文件之间的主要区别在于它们的文件扩展名。 index.php&#xff1a;这是一个标准的 PHP 文件&#xff0c;通常用于编写 PHP 代码。当用户访问 index.php 文件时&#xff0c;Web 服务器…...

主板idyy

import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MachineCodeGenerator { // 获取主板ID&#xff08;这需要根据操作系统具体实现&#xff09; private static String getMotherboardID() {…...

轻松实现向量搜索:探索 Elastic-Embedding-Searcher 项目

随着人工智能和机器学习技术的飞速发展&#xff0c;向量搜索已成为数据检索的重要方式。尤其是在处理大规模文本数据时&#xff0c;传统的基于关键词的检索方式已经难以满足需求。为了优化检索性能并提升搜索精度&#xff0c;向量搜索成为了更加高效的解决方案。而在这一领域&a…...

flask后端开发(3):html模板渲染

目录 渲染模板html模板获取路由参数 gitcode地址&#xff1a; https://gitcode.com/qq_43920838/flask_project.git 渲染模板 这样就能够通过html文件来渲染前端&#xff0c;而不是通过return了 html模板获取路由参数...

逻辑控制语句

一、逻辑控制语句 条件判断 if循环 for、while 二、条件判断 if 1、语法 if 条件:条件为真的操作条件为真的操作 else:条件为假的操作条件为假的操作 data_01 int(input("数字: "))if data_01 > 10:print("ok!!!")print("正确!!!")prin…...

[OpenGL]使用 Compute Shader 实现矩阵点乘

一、简介 本文介绍了如何使用 OpenGL 中的 compute shader 进行矩阵相乘的并行运算。代码目标是&#xff0c;输入两个大小为 10*10 的矩阵 A 和 B&#xff0c;计算 A*B 的结果并存储到矩阵 C 中。 二、代码 0. 代码逻辑 1. 初始化 glfw, glad, 窗口 2. 初始化 compute shad…...

jangow-01-1.0.1靶机

靶机 ip&#xff1a;192.168.152.155 把靶机的网络模式调成和攻击机kali一样的网络模式&#xff0c;我的kali是NAT模式, 在系统启动时(长按shift键)直到显示以下界面 ,我们选第二个&#xff0c;按回车。 继续选择第二个&#xff0c;这次按 e 进入编辑页面 接下来&#xff0c;…...

MySQL 查询大偏移量(LIMIT)问题分析

大偏移量查询缓慢?LIMIT: 会进行两步操作 性能消耗在哪里了?OFFSET操作问题 2 LIMIT 操作 如何优化? 大偏移量查询缓慢? 示例:(假设age字段有索引) SELECT * FROM test WHERE age>18 LIMIT 10000000 ,10;分析MySQL的 LIMIT 10000000 , 10 LIMIT: 会进行两步操作 OFF…...

Docker、containerd、安全沙箱、社区Kata Containers运行对比

大家看了解决有意义、有帮助记得点赞加关注&#xff01;&#xff01;&#xff01; containerd、安全沙箱和Docker三种运行对比。 本文通过对比三种运行时的实现和使用限制、部署结构&#xff0c;帮助您根据需求场景了解并选择合适的容器运行。 一、容器运行时实现和使用限制…...

使用npm包的工程如何引入mapboxgl-enhance/maplibre-gl-enhance扩展包

作者&#xff1a;刘大 前言 在使用iClient for MapboxGL/MapLibreGL项目开发中&#xff0c;往往会对接非EPSG:3857坐标系的地图&#xff0c;由于默认不支持&#xff0c;因此需引入mapboxgl-enhance/maplibre-gl-enhance扩展包。 在使用Vue等其他框架&#xff0c;通过npm包下载…...

【NIFI】实现ORACLE->ORACLE数据同步

【NIFI】实现ORACLE->ORACLE数据同步 需求 使用nifi实现 oracle->oracle 不同数据库之间的数据同步&#xff0c; 如果想实现 oracle->oracle技术有很多&#xff0c;例如使用oracle golden gate或者是kettle等&#xff0c;或者是使用oralce的dblink技术也能实现。当让…...

单例模式的写法

单例模式&#xff08;Singleton Pattern&#xff09;是一种设计模式&#xff0c;确保一个类只有一个实例&#xff0c;并提供一个全局访问点。常用于管理共享资源&#xff08;如数据库连接、配置文件、线程池等&#xff09;。在实际编码中&#xff0c;有多种实现单例模式的方法&…...

Selenium实践总结

1.使用显示等待而不是隐式等待 隐式等待可能会导致不可预测的测试行为&#xff0c;尤其是在动态 Web 应用程序中。显式等待&#xff0c;它允许您 等待特定条件发生后再继续测试&#xff0c;这种方法提供了更多的控制和可靠性。 WebDriverWait wait new WebDriverWait(drive…...

Python数据可视化小项目

英雄联盟S14世界赛选手数据可视化 由于本学期有一门数据可视化课程&#xff0c;课程结课作业要求完成一个数据可视化的小Demo&#xff0c;于是便有了这个小项目&#xff0c;课程老师要求比较简单&#xff0c;只要求熟练运用可视化工具展示数据&#xff0c;并不要求数据来源&am…...

Python毕业设计选题:基于python的白酒数据推荐系统_django+hive

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 白酒管理 系统管理 看板展示 系统首页 白酒详情…...

SQL-leetcode-180. 连续出现的数字

180. 连续出现的数字 表&#xff1a;Logs -------------------- | Column Name | Type | -------------------- | id | int | | num | varchar | -------------------- 在 SQL 中&#xff0c;id 是该表的主键。 id 是一个自增列。 找出所有至少连续出现三次的数字。 返回的…...

Zotero Actions Tags:自动化文献管理,告别手动标签整理

Zotero Actions & Tags&#xff1a;自动化文献管理&#xff0c;告别手动标签整理 【免费下载链接】zotero-actions-tags Customize your Zotero workflow. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-actions-tags 你是否还在为Zotero文献库中杂乱无章的标…...

LangChain实战避坑:我的RAG项目为什么召回结果不准?从向量化到混合检索的调优全记录

LangChain实战调优&#xff1a;从召回失败到精准检索的完整解决方案 当你的RAG系统在回答"夏天旅行推荐"时&#xff0c;返回了撒哈拉沙漠海滩和新疆火山口这类荒谬结果&#xff0c;问题可能出在文本分割、嵌入模型或混合检索策略上。本文将分享一套经过实战验证的调优…...

OEC-turbo变废为宝:从吃灰PCDN盒子到家庭服务器,Armbian/OpenWrt刷机实战记录

OEC-turbo硬件改造指南&#xff1a;从闲置PCDN设备到全能家庭服务器 手上闲置的OEC-turbo盒子除了吃灰还能做什么&#xff1f;这款搭载RK3568芯片的设备实际上是一块被低估的硬件宝藏。相比市面上热门的斐讯N1等矿渣设备&#xff0c;OEC-turbo在处理器性能、内存配置和扩展性方…...

嵌入式系统数据校验算法详解与实践

1. 单片机校验算法的重要性在嵌入式系统开发中&#xff0c;数据校验是确保通信可靠性和数据完整性的基础保障。我从事嵌入式开发十多年来&#xff0c;见过太多因为忽略校验而导致系统故障的案例。比如2018年参与的一个工业控制项目&#xff0c;由于CAN总线通信没有采用CRC校验&…...

从PVT到CST:5种CiA402控制模式在机器人项目中的花式用法(附ROS2配置示例)

从PVT到CST&#xff1a;5种CiA402控制模式在机器人项目中的花式用法&#xff08;附ROS2配置示例&#xff09; 在工业机器人开发中&#xff0c;控制模式的灵活切换往往能解决80%的运动控制难题。当机械臂需要完成高精度装配时&#xff0c;CSP模式能保证微米级定位&#xff1b;执…...

XUnity.AutoTranslator:Unity游戏实时翻译插件终极指南

XUnity.AutoTranslator&#xff1a;Unity游戏实时翻译插件终极指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 还在为看不懂外语游戏而烦恼吗&#xff1f;&#x1f3ae; 语言障碍让多少精彩游戏体验大…...

鸿蒙 ArkTS 高级样式复用:@Extend 装饰器完全解析(比 @Styles 更强大)

&#x1f525;前言&#xff1a;在上一篇文章《鸿蒙 ArkTS 样式复用&#xff1a;Styles 装饰器从入门到实战》中&#xff0c;我们学习了使用 Styles 实现基础样式复用。 但 Styles 不支持传参、不能使用组件专有属性&#xff0c;在复杂 UI 场景下能力有限。 &#x1f4cc; 本文…...

忍者像素绘卷惊艳案例:生成支持CSS Sprite切片的像素角色动作序列图

忍者像素绘卷惊艳案例&#xff1a;生成支持CSS Sprite切片的像素角色动作序列图 1. 像素艺术的新纪元 在游戏开发领域&#xff0c;像素艺术始终保持着独特的魅力。忍者像素绘卷作为一款基于Z-Image-Turbo深度优化的图像生成工具&#xff0c;为开发者带来了革命性的解决方案。…...

告别手动重复!用Python+ArcPy实现多要素批量裁剪年度影像的保姆级教程

PythonArcPy自动化遥感影像裁剪&#xff1a;从原理到实战的完整解决方案 遥感影像处理是GIS工程师的日常必修课。每当拿到新一年的土地利用数据或行政区划影像时&#xff0c;最头疼的莫过于要为每个行政单元单独裁剪每年的数据。我曾花费整整一周时间手动处理30个乡镇5年的NDVI…...

企微API集成指南——从回调到主动发送,全流程代码解析

企业微信提供了丰富的API&#xff0c;用于接收用户添加事件、发送消息、管理标签等。今天从实战角度&#xff0c;给出API集成的最佳实践&#xff0c;附带伪代码。一、核心API清单API用途频率限制获取access_token调用其他API的前提2000次/分钟添加外部联系人通过好友每个号300人…...