将 C++ 使用的 boost 序列化协议导出到 Unity C#

本文介绍了如何在C++和C#之间进行跨平台数据交换,避免使用第三方库如Protobuf。通过在C++中定义自定义的`Serialize`函数,利用C++的`Archive`类记录数据结构和类型,然后生成C#代码,实现C++序列化函数到C#的转换。这种方法虽然在C++看起来笨拙,但能有效实现C++与C#的数据交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果不使用Protobuff这类的工具,想在C++与其他语言之间共享数据似乎是一个大工程,需要写很多的的代码。Protobuff这类工具本身也具有一些问题,比如过度包装,内存,效率等等。而且引入一大堆库也增加了维护难度。C++有自身的序列化方式,最常见的就是 boost 提供的序列化方法(使用C++模板),好用,代码量少,而且简单,而且很容易就可以将这种方法迁移到其他工程里。但这个方法有个问题,几乎不可能将这种方法复制到其他语言环境内。例如C#,本身就不支持模板,而是一种泛型的思路。所以,这种序列化方法注定是c++独有。

但c++的序列化方式非常好用,让我将序列化方式换成Protobuff还真舍不得,但是为了和客户端通讯,似乎又不得不做一些什么。想了很久,找到一个办法,C#不可能像C++那样只需要定义外部Serialize函数即可定义好序列化的协议,唯一的办法就是通过C++读取序列化的协议,来生成C#对应的方法,比如一个c++结构体,通过实现序列化方法。实现了数据传输协议的约定,而我们要做的,就是读取这个协议,然后生成对应的C#的类,来序列化,反序列化这个数据。当然,这个方式就C++来看非常的笨,但没办法,Protobuff也是通过类似的方式来实现的,比如我们把下面这个类通过同样的序列化方法,转译成C#,那么C++与C#之间的通讯就无须采用额外的第三方库。

struct tagTest 
{
	U32 index;
	vector<float> datas;
};


template<class Archive>
inline void Serialize(Archive & archive, tagTest & value, bool isSave)
{
    UNREFERENCED_PARAMETER(isSave);
    archive.Bind( value.index );
    archive.Bind( value.datas );
}

转译成C#:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System;


namespace elapsing
{


    public class tagTest : ISerializable
    {
        public UInt32 index;
        public List<float> datas;


        public tagTest()
        {
            index = default(UInt32);
            datas = new List<float> ();
        }


        public bool Serialize(BytesWriter stream)
        {

            // Member index

            stream.Write(index);

            // Member datas

            UInt32 length_a5778682 = (UInt32)datas.Count;
            UInt16 verify_a5778682 = BytesOperator.InternetCheckSum(System.BitConverter.GetBytes(length_a5778682));

            stream.Write(length_a5778682);
            stream.Write(verify_a5778682);

            for (UInt32 i_a5778682 = 0; i_a5778682 < length_a5778682; ++i_a5778682)
            {
                stream.Write(datas[(Int32)i_a5778682]);
            }

            //End Serialize
            return true;
        }


        public bool Deserialize(BytesReader stream)
        {

            // Member index

            stream.Read( out index);

            // Member datas

            UInt32 length_a5778682 = stream.ReadU32();
            UInt16 verify_a5778682 = stream.ReadU16();

            datas.Clear();
            for (UInt32 i_a5778682 = 0; i_a5778682 < length_a5778682; ++i_a5778682)
            {
                var ds_data = default(float);
                stream.Read( out ds_data);
                datas.Add( ds_data );
            }

            //End Deserialize
            return true;
        }
    }
}

这样也就达到了用C++序列化函数来生成C#代码,并且实现与C#之间数据交互的目的。

为了实现这个目的,主要的设计思路就是用C++的Serialize函数,通过一个额外设计的Archive类来读取Serialize函数内的要序列化的数据名称,类型等信息,然后生成一个完整的树状结构,并且通过这个树状结构为每一层生成具体的对应文件。

注意在Serialize函数中,我们用Bind方法来读或则写数据,但是Bind方法只有一个参数,为了能获取到它的名字,我们用这个办法来获取:

#define Bind(X)        Bind(#X, X)

但相应的,Archive类必须实现对应的方法。

其他的,就贴代码吧,很容易读懂的,第一个是成员的定义的结构体。其中:define是解析后的定义(int float之类),keyptr:如果是map之类,那么key就是map的key的类型,def_dims: 定义的逐层的链表, arr_dims:如果是数组,则记录数组的数据。方法就看名字,很容易理解。

#ifndef TAGMEMBERDEFINE_H
#define TAGMEMBERDEFINE_H
//Begin section for file tagMemberDefine.h
//TODO: Add definitions that you want preserved
//End section for file tagMemberDefine.h
#include "../Common.h"



namespace unity
{



    //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
    struct tagMemberDefine
    {

        //Begin section for unity::tagMemberDefine
        //TODO: Add attributes that you want preserved
        //End section for unity::tagMemberDefine

        public:


            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            typedef CLocalObjectPtr<tagMemberDefine>  Ptr ;


            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            typedef vector<size_t, atom_allocator<size_t> >  Arr ;



        public:


            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            a_string define;



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            Ptr keyptr;



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            Ptr def_dims;



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            Arr arr_dims;



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            tagMemberDefine(); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            tagMemberDefine(const tagMemberDefine & value); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            virtual ~tagMemberDefine(); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            tagMemberDefine & operator =(const tagMemberDefine & value); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool IsPrototype()const ; 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            a_string CreateStatement(a_string var_name); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void ParseClassDefine(a_string def_str); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            a_string RegularClassName(a_string & name); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            a_string Splite(a_string & define, a_string & first); 



    };  //end struct tagMemberDefine



} //end namespace unity



#endif

第二个类,稍微复杂些,派生于tagMemberDefine,parent是上级节点地址,member是成员变量的列表,type是输入的类型(没有解析之前),name是成员变量。方法也是,看名字就知道意思。

#ifndef TAGMEMBER_H
#define TAGMEMBER_H
//Begin section for file tagFoodProperty.h
//TODO: Add definitions that you want preserved
//End section for file tagFoodProperty.h
#include "../Common.h"
#include "tagMemberDefine.h"



namespace unity
{



    //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
    struct tagMember : public tagMemberDefine
    {
        //Begin section for nova::tagFoodProperty
            //TODO: Add attributes that you want preserved
            //End section for nova::tagFoodProperty

        public:


            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            typedef std::list<tagMember, atom_allocator<tagMember> >  Array ;



        public:


            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            unity::tagMember * parent;



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            Array member;



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            a_string type;



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            a_string name;



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            tagMember(); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            tagMember(const tagMember & value); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            virtual ~tagMember(); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            tagMember & operator =(const tagMember & value); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Parse(); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool IsKeyword(a_string & name); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            a_string CreateStatement(); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            a_string DefineStatement(); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            a_string RegularMemberName(a_string & name); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool Scripting(a_string path); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool ScriptingAttach(U32 indent, FILE * file); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool ScriptingDetach(U32 indent, FILE * file); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool ScriptingAttachArray(U32 indent, FILE * file, tagMember & node, U32 level); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool ScriptingDetachArray(U32 indent, FILE * file, tagMember & node, U32 level); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool ScriptingAttachClass(U32 indent, FILE * file, tagMemberDefine & node, a_string name); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool ScriptingDetachClass(U32 indent, FILE * file, tagMemberDefine & node, a_string name); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool ScriptingIndent(U32 indent, FILE * file); 



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void DebugOut(U32 level, a_string indent, U08 flag); 



    };  //end struct tagMember



} //end namespace unity;



#endif

第三个比较重要的就是这个改造的Archive,其实很简单,就是增加一些带名字的方法,然后填充数据结构。

#ifndef UNITY_CARCHIVE_H
#define UNITY_CARCHIVE_H
//Begin section for file CArchive.h
//TODO: Add definitions that you want preserved
//End section for file CArchive.h
#include "../Common.h"
#include "../bind/tagStructure.h"
#include "tagMember.h"



namespace unity
{
    

    
    //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
    class CArchive
    {

        //Begin section for atom::CArchive
        //TODO: Add attributes that you want preserved
        //End section for atom::CArchive

        private:


            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            tagMember root;



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            tagMember * current;



        public:

            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            CArchive() : current( & root )
            {
                //TODO Auto-generated method stub
                root.name = "root";
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            virtual ~CArchive()
            {
                //TODO Auto-generated method stub
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(bool & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type     = "bool";
                member.parent   = current;
                member.Parse();
                current -> member.push_back( member );
            }


            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, bool & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "bool";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }




            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(char & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "char";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, char & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "char";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(I08 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "sbyte";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, I08 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "sbyte";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(I16 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "Int16";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, I16 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "Int16";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(I32 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "Int32";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, I32 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "Int32";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(I64 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "Int64";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, I64 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "Int64";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(U08 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "byte";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }


            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, U08 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "byte";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(U16 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "UInt16";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, U16 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "UInt16";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(U32 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "UInt32";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, U32 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "UInt32";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(U64 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "UInt64";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, U64 & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "UInt64";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(float & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "float";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, float & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "float";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(double & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "double";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, double & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "double";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(a_string & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "string";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, a_string & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "string";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(a_wstring & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "string";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(const char * name, a_wstring & value)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "string";
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Bind(void * buffer, U64 length)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = "byte[]";
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
            }

            

            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void BeginClass(const char * type, const char * name)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = type;
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
                current = & current -> member.back();
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void BeginArray(const char * type, size_t size, const char * name)
            {
                //TODO Auto-generated method stub
                tagMember member;
                member.type = type;
                member.name = name;
                member.parent = current;
                member.Parse();
                current -> member.push_back( member );
                current = & current -> member.back();
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void End()
            {
                //TODO Auto-generated method stub
                current = current -> parent;
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            template <class T>
            void Bind(T & value)
            {
                //TODO Auto-generated method stub
	        	tagStructure<CArchive, T, true>::Serialize( * this, "", value );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            template <class T>
            void Bind(const T & value)
            {
                //TODO Auto-generated method stub
                Bind( const_cast<T &>(value) );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            template <class T>
            void Bind(const char * name, T & value)
            {
                //TODO Auto-generated method stub
	        	tagStructure<CArchive, T, true>::Serialize( *this, name, value );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            template <class T>
            void Bind(const char * name, const T & value)
            {
                //TODO Auto-generated method stub
                Bind( name, const_cast<T &>(value) );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            template <class T>
            inline CArchive & operator <<(T & value)
            {
                //TODO Auto-generated method stub
                Bind( value );
                return( *this );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            template <class T>
            inline CArchive & operator <<(const T & value)
            {
                //TODO Auto-generated method stub
                Bind( value );
                return( *this );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            template <class T>
            inline CArchive & operator >>(T & value)
            {
                //TODO Auto-generated method stub
                Bind( value );
                return( *this );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Print()
            {
                //TODO Auto-generated method stub
                root.DebugOut( 0, "", 0 );
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Assign(const CMemory & data)
            {
                //TODO Auto-generated method stub
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            void Clone(CMemory & data)
            {
                //TODO Auto-generated method stub
            }



            //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
            bool Scripting(const char * path)
            {
                //TODO Auto-generated method stub
                return root.member.front().Scripting( path );
            }



    };  //end class CArchive



} //end namespace atom



#endif

需要对序列化Array和class的模板稍作修改:

#ifndef UNITY_TAGARRAY_H
#define UNITY_TAGARRAY_H
//Begin section for file tagArray.h
//TODO: Add definitions that you want preserved
//End section for file tagArray.h
#include "../Common.h"


namespace unity
{
	
	//@uml.annotationsderived_abstraction="platform:/resource/SystemInterface/document/System%20Interface.emx#_GwgikKxjEdyG2OUyJIn0qA"
	//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
	template <class A, class T, bool save>
	struct tagArray
	{
	
	    //Begin section for si::tagArray
	    //TODO: Add attributes that you want preserved
	    //End section for si::tagArray
	    public:
	
	        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
	        inline static void Invoke(A & ar, const char * name, T & t)
	        {
	        	//TODO Auto-generated method stub
	        	// 读取或写入数组的长度;
	        	U32 bound = static_cast<U32>( array_trait<T>::bound );

			ar.BeginArray( typeid(T).name(), bound, name );

                        U32 limit = bound;
	        	ar.Bind( bound );

                        // 确认数组的长度是否越界;
                        bound = atom_min( bound, limit );
	        	
	        	// 读取或写入数组的元素;
	        	for( size_t i = 0; i < bound; ++ i )
	        	{
	        		ar.Bind( t[i] );
	        	}

			ar.End();
	        }
	
	};  //end struct tagArray
	
} // end namespace atom

#endif
#ifndef UNITY_TAGCLASS_H
#define UNITY_TAGCLASS_H
//Begin section for file tagClass.h
//TODO: Add definitions that you want preserved
//End section for file tagClass.h



namespace unity
{

	//@uml.annotationsderived_abstraction="platform:/resource/SystemInterface/document/System%20Interface.emx#_gQx30KxjEdyG2OUyJIn0qA"
	//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
	template <class A, class T, bool save>
	struct tagClass
	{
	
	    //Begin section for si::tagClass
	    //TODO: Add attributes that you want preserved
	    //End section for si::tagClass
	    public:
	
	        //@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
	        inline static void Invoke(A & ar, const char * name, T & t)
	        {
	        	//TODO Auto-generated method stub
			ar.BeginClass( typeid(T).name(), name );
	        	Serialize( ar, t, save );
			ar.End();
	        }
	
	};  //end struct tagClass
	
} // end namespace atom

#endif

最后就是两个结构体方法的实现:

#include "tagMemberDefine.h"
//Begin section for file tagMemberDefine.cpp
//TODO: Add definitions that you want preserved
//End section for file tagMemberDefine.cpp


//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
unity::tagMemberDefine::tagMemberDefine()
{
    //TODO Auto-generated method stub
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
unity::tagMemberDefine::tagMemberDefine(const tagMemberDefine & value) :
define(value.define),keyptr(value.keyptr),def_dims(value.def_dims),arr_dims(value.arr_dims)
{
    //TODO Auto-generated method stub
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
unity::tagMemberDefine::~tagMemberDefine() 
{
    //TODO Auto-generated method stub
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
unity::tagMemberDefine & unity::tagMemberDefine::operator =(const tagMemberDefine & value) 
{
    //TODO Auto-generated method stub
    define   = value.define;
    keyptr   = value.keyptr;
    def_dims = value.def_dims;
    arr_dims = value.arr_dims;
    return( * this );
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool unity::tagMemberDefine::IsPrototype() const 
{
    //TODO Auto-generated method stub
    bool result = false;

    #define MAX_PROTOTYPE 20
    static char * prototype[] = {
        "bool",
        "char",
        "byte",
        "sbyte",
		"int",
        "uint",
        "short",
        "ushort",
        "long",
        "ulong",
        "Int16",
        "UInt16",
        "Int32",
        "UInt32",
        "Int64",
        "UInt64",
        "float",
        "double",
        "decimal",
        "string",
    };

    for( size_t i = 0; i < MAX_PROTOTYPE; ++ i )
    {
        if( define == prototype[i] ) {
            result = true; break;
        }
    }

    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
a_string unity::tagMemberDefine::CreateStatement(a_string var_name) 
{
    //TODO Auto-generated method stub
    a_string result;

    // 如果不是原型,或则有数组,则用new;
    if( !IsPrototype() || !arr_dims.empty() )
    {
        result += var_name;
        result += " = new ";

        // 遍历数组深度
        size_t total = 0; Ptr value = * this;

        do
        {
            // 增加定义
            result += value -> define;

            // 如果有子类,继续
            if( value -> def_dims ) 
            {
                result += "<";
                if( value -> keyptr )
                {
                    result += value -> keyptr -> define;
                    result += ", ";
                }
                ++ total;
            }

            // 遍历下一个
            value = value -> def_dims;

        } while( value );

        // 恢复尖括号
        for( size_t i = 0; i < total; ++ i )
        {
            result += "> ";
        }

        // 如果是类,并且没有维度;
        // 原型不需要()
        // 数组不需要()
        if( !IsPrototype() && arr_dims.empty() )
        {
            result += "()";
        }

        // 如果有维度,则增加数组的定义;
        if( !arr_dims.empty() ) 
        {
            result += "[";
            for( size_t i = 0, j = arr_dims.size(); i < j; ++ i )
            {
                char msg[32];
                sprintf( msg, "%llu", arr_dims[i] );
                result += msg;

                // 逗号个数要减一;
                if( i + 1 < j ) {
                    result += ",";
                }
            }
            result += "]";
        }
    }


    // 原型,可以直接用default来处理;
    else
    {
        result += var_name;
        result += " = default(";
        result += define;
        result += ")";
    }

    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
void unity::tagMemberDefine::ParseClassDefine(a_string def_str) 
{
    //TODO Auto-generated method stub
    a_string::size_type 
        pos_1 = a_string::npos, 
        pos_2 = a_string::npos;

    // 判断array,必须考虑内嵌对象的数组形式 vector<a[10]> [10]
    for( ; ; )
    {
        // 从后往前找方括号 [
        pos_1 = def_str.rfind( '[' );
        if( pos_1 == a_string::npos ) {
            break;
        }

        // 从pos_1位置开始,从前往后找方括号 ]
        pos_2 = def_str.find( ']', pos_1 );
        if( pos_2 == a_string::npos )
        {
            CLog log;
            log << "Invalid class declare string: " << def_str << end_error;

            exit(-1);
            break;
        }

        //  从pos_2开始,到最后除了空格不能有任何其他字符
        if( def_str.find_first_not_of("] ", pos_2) != a_string::npos )
        {
            break;
        }

        // 将维度的值解析出来,并插入到数组的首部位置;
        arr_dims.insert( arr_dims.begin(), 
            atoi( def_str.substr(pos_1 + 1, pos_2 - pos_1 - 1).c_str() ) );

        // 剪切字符串,去掉最后一个数组定义
        def_str = trim( def_str.substr(0, pos_1) );
    }
        
    // 再解析对象;
    for( ;; )
    {
        // 从开始找第一个尖括号 <
        pos_1 = def_str.find( '<' );
        if( pos_1 == a_string::npos ) {
            break;
        }

        // 从后开始找第一个尖括号 >
        pos_2 = def_str.rfind( '>' );
        if( pos_2 == a_string::npos )
        {
            CLog log;
            log << "Invalid class declare string: " << def_str << end_error;

            exit(-1);
            break;
        }

        // 先取出类名
        define = RegularClassName( def_str.substr(0, pos_1) );

        // 取出子类的定义(不包括尖括号<>)
        a_string sub_class = def_str.substr( pos_1 + 1, pos_2 - pos_1 - 1 );

        // 如果是字符串,则不再继续解析;
        if( define == "basic_string") {
            define = "string";
            break;
        }

        // 如果是map,则拆分key和value
        else
        if( define == "map" )
        {
            // 直接指定为C#内的字典
            define = "Dictionary";
            
            // 准备取出map的key类型
            a_string key_class;
            sub_class = Splite( sub_class, key_class );

            // 递归解析key的值,并赋予keyptr
            tagMemberDefine key;
            key.ParseClassDefine( key_class );
            keyptr = key;
            
            // 解析value的类型,
            Splite( sub_class, sub_class );
        }


        // 其他容器,vector list set 之类的,用C# List代替
        else
        if( define == "vector" || define == "list" || define == "set" )
        {
            define = "List";

            // 解析value的类型,
            Splite( sub_class, sub_class );
        }
        else
        {
            CLog log;
            log << "Unknow container type: " << sub_class << end_error;

            exit(-1);
            break;
        }

        tagMemberDefine next;
        next.ParseClassDefine( sub_class );
        def_dims = next;
        break;
    }

    // 如果不是容器类对象,则解析类名
    if( define.empty() ) {
        define = RegularClassName( def_str );
    }
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
a_string unity::tagMemberDefine::RegularClassName(a_string & clsname) 
{
    //TODO Auto-generated method stub
    if( clsname.empty() ) {
        return clsname;
    }

    // 去掉class关键字
    size_t offset = clsname.find("class ");
    if( offset != a_string::npos ) {
        clsname.erase( 0, offset + strlen("class") );
    }

    // 去掉struct关键字
    offset = clsname.find("struct ");
    if( offset != a_string::npos ) {
        clsname.erase( 0, offset + strlen("struct") );
    }

    // 去掉所有的命名空间
    offset = clsname.rfind("::");
    if( offset != a_string::npos ) {
        clsname.erase( 0, offset + strlen("::") );
    }

    // 替换一些不同的定义方式
    typedef map<a_string, a_string, less<a_string>, atom_allocator<pair<const a_string, a_string> > > CPrototypeMap;
    CPrototypeMap replace;
    replace.insert( make_pair("unsigned char",      "byte") );
    replace.insert( make_pair("unsigned short",     "UInt16") );
    replace.insert( make_pair("unsigned int",       "UInt32") );
    replace.insert( make_pair("unsigned __int8",    "byte") );
    replace.insert( make_pair("unsigned __int16",   "UInt16") );
    replace.insert( make_pair("unsigned __int32",   "UInt32") );
    replace.insert( make_pair("unsigned __int64",   "UInt64") );
    replace.insert( make_pair("__int8",             "sbyte") );
    replace.insert( make_pair("__int16",            "Int16") );
    replace.insert( make_pair("__int32",            "Int32") );
    replace.insert( make_pair("__int64",            "Int64") );

    CPrototypeMap::const_iterator 
        it  = replace.find( clsname );
    if( it != replace.end() ) {
        clsname = it -> second;
    }

    return trim( clsname );
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
a_string unity::tagMemberDefine::Splite(a_string & clsstr, a_string & subcls)
{
    //TODO Auto-generated method stub
    a_string result;
    a_string key_class; size_t offset = 0;
    for( ;; )
    {
        size_t r(0), l(0);

        // 查找key结束的逗号位置;
        offset = clsstr.find( ',', offset + 1 );
        if( offset != a_string::npos )
        {
            // 统计 <> 的个数,必须相等,才是一个完整的定义
            for( size_t i = 0; i < offset; ++ i )
            {
                if( clsstr.at(i) == '<' ) {
                    l ++;
                }

                if( clsstr.at(i) == '>' ) {
                    r ++;
                }
            }
        }

        if( r == l )
        {
            // 如果offset有效,则在此点分割前后;
            if( offset != a_string::npos ) 
            {
                result = clsstr.substr( offset + 1 );
                subcls = clsstr.substr( 0, offset  );
            }

            // 如果offset无效,则将全部复制给subcls
            else
            {
                subcls = clsstr;
            }
            break;
        }
    }
    return result;
}
#include "tagMember.h"
//Begin section for file tagMember.cpp
//TODO: Add definitions that you want preserved
//End section for file tagMember.cpp


//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
unity::tagMember::tagMember() : 
parent(NULL)
{
    //TODO Auto-generated method stub
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
unity::tagMember::tagMember(const tagMember & value) : 
tagMemberDefine(value),parent(value.parent),member(value.member),type(value.type),name(value.name)
{
    //TODO Auto-generated method stub
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
unity::tagMember::~tagMember() 
{
    //TODO Auto-generated method stub
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
unity::tagMember & unity::tagMember::operator =(const tagMember & value) 
{
    //TODO Auto-generated method stub
    tagMemberDefine::operator=( value );
    type    = value.type;
    name    = value.name;
    member  = value.member;
    parent  = value.parent;
    return( * this );
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
void unity::tagMember::Parse() 
{
    //TODO Auto-generated method stub
    // 先规整命名,再分析类型
    RegularMemberName( name );
    ParseClassDefine ( type );
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool unity::tagMember::IsKeyword(a_string & value) 
{
    //TODO Auto-generated method stub
    bool result = false;
    #define MAX_KEYWORD 81
    static char * key_word[MAX_KEYWORD] = {
        "abstract",
        "as",
        "base",
        "bool",
        "break",
        "byte",
        "case",
        "catch",
        "char",
        "checked",
        "class",
        "const",
        "continue",
        "decimal",
        "default",
        "delegate",
        "do",
        "double",
        "else",
        "enum",
        "ecent",
        "explicit",
        "extern",
        "false",
        "finally",
        "fixed",
        "float",
        "for",
        "foreach",
        "get",
        "goto",
        "if",
        "implicit",
        "in",
        "int",
        "interface",
        "internal",
        "is",
        "lock",
        "long",
        "namespace",
        "new",
        "null",
        "object",
        "out",
        "override",
        "partial",
        "private",
        "protected",
        "public",
        "readonly",
        "ref",
        "return",
        "sbyte",
        "sealed",
        "set",
        "short",
        "sizeof",
        "stackalloc",
        "static",
        "struct",
        "switch",
        "this",
        "throw",
        "true",
        "try",
        "typeof",
        "uint",
        "ulong",
        "unchecked",
        "unsafe",
        "ushort",
        "using",
        "value",
        "virtual",
        "volatile",
        "volatile",
        "void",
        "where",
        "while",
        "yield"
    };
     
    for( size_t i = 0; i < MAX_KEYWORD; ++ i )
    {
        if( value == key_word[i] ) {
            result = true; break;
        }
    }
    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
a_string unity::tagMember::CreateStatement() 
{
    //TODO Auto-generated method stub
    return tagMemberDefine::CreateStatement( name );
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
a_string unity::tagMember::DefineStatement() 
{
    //TODO Auto-generated method stub
    a_string result;
    size_t total = 0; Ptr value = * this;

    do
    {
        result += value -> define;
        if( value -> def_dims ) 
        {
            result += "<";
            if( value -> keyptr )
            {
                result += value -> keyptr -> define;
                result += ", ";
            }
            ++ total;
        }

        value = value -> def_dims;

    } while( value );

    for( size_t i = 0; i < total; ++ i )
    {
        result += ">";
    }


    if( !arr_dims.empty() ) 
    {
        result += "[";
        for( size_t i = 1; i < arr_dims.size(); ++ i ) {
            result += ",";
        }
        result += "]";
    }
    
    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
a_string unity::tagMember::RegularMemberName(a_string & member_name) 
{
    //TODO Auto-generated method stub
    if( member_name.empty() ) {
        return member_name;
    }

    // 去掉所有的类联系
    size_t offset = member_name.rfind('.');
    if( offset != a_string::npos ) {
        member_name.erase( 0, offset + 1 );
    }

    trim( member_name );

    // 增加前缀避免c++与c#之间不同的关键字
    if( IsKeyword(member_name) ) {
        member_name = "_" + member_name;
    }

    return member_name;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool unity::tagMember::Scripting(a_string path) 
{
    //TODO Auto-generated method stub
    bool result = false;
    a_string filename = path + "/" + define + ".cs";

    FILE * file = fopen( filename.c_str(), "w+" );
    if( file )
    {
        result = true;

        // 包含定义
        fprintf( file, "using System.Collections;\n" );
        fprintf( file, "using System.Collections.Generic;\n" );
        fprintf( file, "using System.IO;\n" );
        fprintf( file, "using System;\n\n\n" );

        // 命名空间
        fprintf( file, "namespace elapsing\n" );
        fprintf( file, "{\n\n\n" );

        // 类定义
        fprintf( file, "    public class %s : ISerializable\n", define.c_str() );
        fprintf( file, "    {\n" );

        // 成员变量,只处理本级的变量;
        for( tagMember::Array::iterator
            it = member.begin(); it != member.end(); ++ it )
        {
            fprintf( file, "        public %s %s;\n", it -> DefineStatement().c_str(), it -> name.c_str() );
        }

        // 构造函数
        fprintf( file, "\n\n" );
        fprintf( file, "        public %s()\n", define.c_str() );
        fprintf( file, "        {\n" );

        // 创建成员变量,只创建本级的变量;
        for( tagMember::Array::iterator
            it = member.begin(); it != member.end(); ++ it )
        {
            a_string create = it -> CreateStatement();
            if( !create.empty() ) {
                fprintf( file, "            %s;\n", create.c_str() );
            }
        }

        fprintf( file, "        }\n" );

        // 序列化函数
        fprintf( file, "\n\n" );
        fprintf( file, "        public bool Serialize(BytesWriter stream)\n" );
        fprintf( file, "        {\n" );

        for( tagMember::Array::iterator
            it = member.begin(); it != member.end(); ++ it )
        {
            // 第一级都是3层缩进
            fprintf( file, "\n" );
            fprintf( file, "            // Member %s\n", it -> name.c_str() );
            fprintf( file, "\n" );

            result = it -> ScriptingAttach( 3, file ) && result;
        }

        fprintf( file, "\n            //End Serialize\n" );
        fprintf( file, "            return true;\n" );
        fprintf( file, "        }\n" );
        fprintf( file, "\n\n" );

        // 反序列化函数
        fprintf( file, "        public bool Deserialize(BytesReader stream)\n" );
        fprintf( file, "        {\n" );

        for( tagMember::Array::iterator
            it = member.begin(); it != member.end(); ++ it )
        {
            // 第一级都是3层缩进
            fprintf( file, "\n" );
            fprintf( file, "            // Member %s\n", it -> name.c_str() );
            fprintf( file, "\n" );

            result = it -> ScriptingDetach( 3, file ) && result;
        }

        // 反序列化结束
        fprintf( file, "\n            //End Deserialize\n" );
        fprintf( file, "            return true;\n" );
        fprintf( file, "        }\n" );
    

        // 类结束,命名空间结束
        fprintf( file, "    }\n" );
        fprintf( file, "}\n" );

        fclose( file );
    }
    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool unity::tagMember::ScriptingAttach(U32 indent, FILE * file) 
{
    //TODO Auto-generated method stub
    bool result = false;
    if( file )
    {
        // 首先处理数组
        if( arr_dims.empty() == false )
        {
            result = ScriptingAttachArray( indent, file, * this, 0 );
        }

        // 处理类
        else
        {
            result = ScriptingAttachClass( indent, file, * this, name );
        }
    }
    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool unity::tagMember::ScriptingDetach(U32 indent, FILE * file) 
{
    //TODO Auto-generated method stub
    bool result = false;
    if( file )
    {
        // 首先处理数组
        if( arr_dims.empty() == false )
        {
            result = ScriptingDetachArray( indent, file, * this, 0 );
        }

        // 处理类
        else
        {
            result = ScriptingDetachClass( indent, file, * this, name );
        }
    }
    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool unity::tagMember::ScriptingAttachArray(U32 indent, FILE * file, tagMember & node, U32 level)
{
    //TODO Auto-generated method stub
    bool result = false;
    if( file )
    {
        if( level == node.arr_dims.size() ) {
            return ScriptingAttachClass( indent + level, file, node, node.name );
        }

        atom_hash<a_string> hasher;
        U32 hash = static_cast<U32>( hasher(node.name) );

        ScriptingIndent( indent + level, file );
        fprintf( file, "UInt32 length_%08x_%lu = %zu;\n", hash, level + 1, node.arr_dims[level] );

        ScriptingIndent( indent + level, file );
        fprintf( file, "stream.Write(length_%08x_%lu);\n", hash, level + 1 );
                
        fprintf( file, "\n" );

        ScriptingIndent( indent + level, file );
        fprintf( file, "for (UInt32 i_%lu = 0; i_%lu < length_%08x_%lu; ++i_%lu)\n", level + 1, level + 1, hash, level + 1, level + 1  );

        ScriptingIndent( indent + level, file );
        fprintf( file, "{\n" );

        result = ScriptingAttachArray( indent, file, node, level + 1 );
                
        ScriptingIndent( indent + level, file );
        fprintf( file, "}\n" );
    }
    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool unity::tagMember::ScriptingDetachArray(U32 indent, FILE * file, tagMember & node, U32 level)
{
    //TODO Auto-generated method stub
    bool result = false;
    if( file )
    {
        if( level == node.arr_dims.size() ) {
            return ScriptingDetachClass( indent + level, file, node, node.name );
        }

        atom_hash<a_string> hasher;
        U32 hash = static_cast<U32>( hasher(node.name) );

        ScriptingIndent( indent + level, file );
        fprintf( file, "UInt32 lenmax_%08x_%lu = %zu;\n", hash, level + 1, node.arr_dims[level] );

        ScriptingIndent( indent + level, file );
        fprintf( file, "UInt32 length_%08x_%lu = stream.ReadU32();\n", hash, level + 1 );
                
        ScriptingIndent( indent + level, file );
        fprintf( file, "length_%08x_%lu = Math.Min(length_%08x_%lu, lenmax_%08x_%lu);\n", hash, level + 1, hash, level + 1, hash, level + 1 );

        fprintf( file, "\n" );

        ScriptingIndent( indent + level, file );
        fprintf( file, "for (UInt32 i_%lu = 0; i_%lu < length_%08x_%lu; ++i_%lu)\n", level + 1, level + 1, hash, level + 1, level + 1  );

        ScriptingIndent( indent + level, file );
        fprintf( file, "{\n" );

        ScriptingDetachArray( indent, file, node, level + 1);
                
        ScriptingIndent( indent + level, file );
        fprintf( file, "}\n" );
    }
    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool unity::tagMember::ScriptingAttachClass(U32 indent, FILE * file, tagMemberDefine & node, a_string node_name)
{
    //TODO Auto-generated method stub
    bool result = false;
    if( !file ) {
        return false;
    }

    a_string text = node_name;

    // 获取名字的哈希值
    atom_hash<a_string> hasher;
    U32 hash = static_cast<U32>( hasher(node_name) );
    
    // 处理数组
    if( !node.arr_dims.empty() )
    {
        text += "[";
        for( U32 i = 0, j = 
            static_cast<U32>( node.arr_dims.size() ); i < j; ++ i )
        {
            char msg[16];
            sprintf( msg, "%lu", i + 1 );

            text += "i_";
            text += msg;
            
            if( i + 1 < j ) {
                text += ",";
            }
        }
        text += "]";
    }

    // 如果 node 是原型,或则是 byte[] 则直接写;
    if( node.IsPrototype() || node.define == "byte[]" )
    {
        text = "stream.Write(" + text + ");";
        ScriptingIndent( indent, file );
        fprintf( file, "%s\n", text.c_str() );
        result = true;
    }


    // 如果是 Dictionary 容器,key / value
    else
    if( node.define == "Dictionary" )
    {
        ScriptingIndent( indent, file );
        fprintf( file, "UInt32 length_%08x = (UInt32)%s.Count;\n", hash, node_name.c_str() );

        ScriptingIndent( indent, file );
        fprintf( file, "UInt16 verify_%08x = BytesOperator.InternetCheckSum(System.BitConverter.GetBytes(length_%08x));\n\n", hash, hash );
        
        ScriptingIndent( indent, file );
        fprintf( file, "stream.Write(length_%08x);\n", hash );
                
        ScriptingIndent( indent, file );
        fprintf( file, "stream.Write(verify_%08x);\n", hash );

        fprintf( file, "\n" );

        ScriptingIndent( indent, file );
        fprintf( file, "foreach(var key_%08x in %s.Keys)\n", hash, node_name.c_str()  );

        ScriptingIndent( indent, file );
        fprintf( file, "{\n" );

        // write key;
        char msg[16];
        sprintf( msg, "key_%08x", hash );
        if( node.keyptr ) {
            result = ScriptingAttachClass( indent + 1, file, * node.keyptr, msg );
        }

        // write value;
        a_string next_name = node_name + "[" + msg + "]";
        if( node.def_dims ) {
            result = ScriptingAttachClass( indent + 1, file, * node.def_dims, next_name ) && result;
        }

        ScriptingIndent( indent, file );
        fprintf( file, "}\n" );
    }


    // 如果是List容器
    else
    if( node.define == "List" )
    {
        ScriptingIndent( indent, file );
        fprintf( file, "UInt32 length_%08x = (UInt32)%s.Count;\n", hash, node_name.c_str() );

        ScriptingIndent( indent, file );
        fprintf( file, "UInt16 verify_%08x = BytesOperator.InternetCheckSum(System.BitConverter.GetBytes(length_%08x));\n\n", hash, hash );
        
        ScriptingIndent( indent, file );
        fprintf( file, "stream.Write(length_%08x);\n", hash );
                
        ScriptingIndent( indent, file );
        fprintf( file, "stream.Write(verify_%08x);\n", hash );

        fprintf( file, "\n" );

        ScriptingIndent( indent, file );
        fprintf( file, "for (UInt32 i_%08x = 0; i_%08x < length_%08x; ++i_%08x)\n", hash, hash, hash, hash  );

        ScriptingIndent( indent, file );
        fprintf( file, "{\n" );

        // write value;
        char msg[16];
        sprintf( msg, "i_%08x", hash );
        a_string next_name = node_name + "[(Int32)" + msg + "]";

        if( node.def_dims ) {
            result = ScriptingAttachClass( indent + 1, file, * node.def_dims, next_name );
        }

        ScriptingIndent( indent, file );
        fprintf( file, "}\n" );
    }


    // 类的类型
    else
    {
        text = text + ".Serialize(stream);";
        ScriptingIndent( indent, file );
        fprintf( file, "%s\n", text.c_str() );
        result = true;
    }

    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool unity::tagMember::ScriptingDetachClass(U32 indent, FILE * file, tagMemberDefine & node, a_string node_name)
{
    //TODO Auto-generated method stub
    bool result = false;
    if( !file ) {
        return false;
    }

    a_string text = node_name;

    // 处理哈希值
    atom_hash<a_string> hasher;
    U32 hash = static_cast<U32>( hasher(node_name) );
    
    // 处理数值
    if( !node.arr_dims.empty() )
    {
        text += "[";
        for( U32 i = 0, j = 
            static_cast<U32>( node.arr_dims.size() ); i < j; ++ i )
        {
            char msg[16];
            sprintf( msg, "%d", i + 1);

            text += "i_";
            text += msg;

            if( i + 1 < j ) {
                text += ",";
            }
        }
        text += "]";
    }


    // 如果是原型,则用标准方法读取;
    if( node.IsPrototype() )
    {
        text = "stream.Read( out " + text + ");";
        ScriptingIndent( indent, file );
        fprintf( file, "%s\n", text.c_str() );
        result = true;
    }


    // 如果是 Dictionary ,则读取 key, value
    else
    if( node.define == "Dictionary" )
    {
        ScriptingIndent( indent, file );
        fprintf( file, "UInt32 length_%08x = stream.ReadU32();\n", hash );

        ScriptingIndent( indent, file );
        fprintf( file, "UInt16 verify_%08x = stream.ReadU16();\n", hash );

        fprintf( file, "\n" );

        ScriptingIndent( indent, file );
        fprintf( file, "%s.Clear();\n", node_name.c_str()  );

        ScriptingIndent( indent, file );
        fprintf( file, "for(UInt32 i_%08x = 0; i_%08x < length_%08x; ++ i_%08x)\n", hash, hash, hash, hash );

        ScriptingIndent( indent, file );
        fprintf( file, "{\n" );

        char msg[16];
        sprintf( msg, "key_%08x", hash );

        // create key;
        a_string create_string;
        if( node.keyptr ) {
            create_string = node.keyptr -> CreateStatement( a_string(msg) );
            result = true;
        }

        // read key;
        ScriptingIndent( indent + 1, file );
        fprintf( file, "var %s;\n", create_string.c_str() );

        if( node.keyptr ) {
            result = ScriptingDetachClass( indent + 1, file, * node.keyptr, msg ) && result;
        }

        // read value;
        a_string next_name = node_name + "[" + msg + "]";
        if( node.def_dims ) {
            result = ScriptingDetachClass( indent + 1, file, *node.def_dims, next_name ) && result;
        }

        ScriptingIndent( indent, file );
        fprintf( file, "}\n" );
    }



    // 如果是 List 容器
    else
    if( node.define == "List" )
    {
        ScriptingIndent( indent, file );
        fprintf( file, "UInt32 length_%08x = stream.ReadU32();\n", hash );

        ScriptingIndent( indent, file );
        fprintf( file, "UInt16 verify_%08x = stream.ReadU16();\n", hash );

        fprintf( file, "\n" );

        ScriptingIndent( indent, file );
        fprintf( file, "%s.Clear();\n", node_name.c_str()  );

        ScriptingIndent( indent, file );
        fprintf( file, "for (UInt32 i_%08x = 0; i_%08x < length_%08x; ++i_%08x)\n", hash, hash, hash, hash  );

        ScriptingIndent( indent, file );
        fprintf( file, "{\n" );

        // 创建对象
        a_string create_string = "var ";
        if( node.def_dims ) {
            create_string += node.def_dims -> CreateStatement( a_string("ds_data") );
            result = true;
        }
        
        ScriptingIndent( indent + 1, file );
        fprintf( file, "%s;\n", create_string.c_str() );

        // 读取
        if( node.def_dims ) {
            result = ScriptingDetachClass( indent + 1, file, * node.def_dims, a_string("ds_data") ) && result;
        }

        // 添加到array
        a_string add_action = node_name + ".Add( ds_data );";

        ScriptingIndent( indent + 1, file );
        fprintf( file, "%s\n", add_action.c_str() );

        ScriptingIndent( indent, file );
        fprintf( file, "}\n" );
    }


    // 如果是 byte[],则需要手工输入一个length。
    else
    if( node.define == "byte[]" )
    {
        // 内存块
        text += " = stream.ReadBytes(<input length here>);";
        ScriptingIndent( indent, file );
        fprintf( file, "%s\n", text.c_str() );
        result = true;
    }


    // 类的类型
    else
    {
        text = text + ".Deserialize(stream);";
        ScriptingIndent( indent, file );
        fprintf( file, "%s\n", text.c_str() );
        result = true;
    }

    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
bool unity::tagMember::ScriptingIndent(U32 indent, FILE * file)
{
    //TODO Auto-generated method stub
    bool result = false;
    if( file )
    {
        result = true;
        for( U32 t = 0; t < indent; ++ t ) {
            fprintf( file, "    " );
        }
    }
    return result;
}

//@generated "UML to C++ (com.ibm.xtools.transform.uml2.cpp.CPPTransformation)"
void unity::tagMember::DebugOut(U32 level, a_string indent, U08 flag)
{
    //TODO Auto-generated method stub
    a_string buffer;    
    buffer += indent;

    switch( flag )
    {
    case 0:
        buffer += "└─┬ ";
        break;
    case 1:
        buffer += "  ├ ";
        break;
    case 2:
        buffer += "  └ ";
        break;
    case 3:
        buffer += "└── ";
        break;

    case 4:
        buffer += "├─┬ ";
        break;
    case 5:
        buffer += "│ ├ ";
        break;
    case 6:
        buffer += "│ └ ";
        break;
    }

    size_t total = 0; Ptr value = * this;
    do
    {
        buffer += value -> define;
        if( value -> def_dims ) 
        {
            buffer += "<";
            if( value -> keyptr )
            {
                buffer += value -> keyptr -> define;
                buffer += ", ";
            }
            ++ total;
        }

        value = value -> def_dims;

    } while( value );


    for( size_t i = 0; i < total; ++ i ) {
        buffer += ">";
    }

    if( !arr_dims.empty() ) 
    {
        for( size_t i = 0; i < arr_dims.size(); ++ i )
        {
            char msg[32];
            sprintf( msg, "%llu", arr_dims[i] );
            buffer += "[";
            buffer += msg;
            buffer += "]";
        }
    }

    buffer += " ";
    buffer += name;
    buffer += "\n";

    printf( buffer.c_str() );

    size_t parent_members = 0;
    bool is_last = false;
    if( parent )
    {
        parent_members = parent -> member.size();
        if( parent_members ) 
        {
            is_last = ( this == & parent -> member.back() );
        }
    }

    size_t grand_parent_members = 0;
    if( parent && parent -> parent )
    {
        grand_parent_members = parent -> parent -> member.size();
    }

    for( tagMember::Array::iterator
        it = member.begin(); it != member.end(); ++ it )
    {
        U32 shift = 0;
        a_string sub_indent = indent;

        if( grand_parent_members > 1 && parent_members > 1 )
        {
            sub_indent += "│ ";
        }
        else
        {
            sub_indent += "  ";
        }

        if( parent_members > 1 && member.size() > 1 && !is_last )
        {
            shift = 4;
        }

        // 如果是第一项
        if( it == member.begin() ) 
        {
            // 如果有多个子节点
            if( member.size() > 1 )
            {
                it -> DebugOut( level + 1, sub_indent, 0 + shift );
            }

            // 如果只有一个子节点
            else
            {
                // 子节点没有子节点
                if( it -> member.empty() ) 
                {
                    it -> DebugOut( level + 1, sub_indent, 3 + shift );
                }
                else
                {
                    it -> DebugOut( level + 1, sub_indent, 0 + shift );
                }
            }
        }

        // 如果是最后一项
        else
        if( it == prev( member.end() ) )
        {
            // 有子节点
            if( !it -> member.empty() )
            {
                it -> DebugOut( level + 1, sub_indent, 1 + shift );
            }

            // 如果没有子节点
            else 
            {
                it -> DebugOut( level + 1, sub_indent, 2 + shift );
            }
        }
        
        // 中间项
        else
        {
            it -> DebugOut( level + 1, sub_indent, 1 + shift );
        }
    }
}

到此,大功告成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值