C# C++ 相互序列化

最近项目需要,为了解决C++和C#之间Socket通信,能够传对象。
写了个C++序列化的功能主要是兼容C#序列化的格式,这样用C++序列化的xml,可以用C#反序列化回来,反之同理。
不敢藏起来,拿出来同大家分享。

话不多说,直接上代码。http://files.cnblogs.com/ShadowK/seri.rar

C#部分。

ContractedBlock.gif ExpandedBlockStart.gif Code
ExpandedBlockStart.gifContractedBlock.gif /**//// <summary>
    
/// 对应C++版本相同的类。C++版本字段只能CString类型。
    
/// C#可以为string, int, enum, float, 
    
///         DataTime(C++赋值的时候要符合格式"2008-11-06T01:01:01")
    
///         其它的没有试过。应该都可以。
    
/// </summary>

    public class MidClass
ExpandedBlockStart.gifContractedBlock.gif    
{
        
public string P1;
    }


    
public class TestClass
ExpandedBlockStart.gifContractedBlock.gif    
{
        
public int P1;
        
public List<int> P2 = new List<int>();
        
public MidClass P3;
        
public List<MidClass> P4;
    }


    
class Program
ExpandedBlockStart.gifContractedBlock.gif    
{
        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        

            TestClass t1 
= new TestClass();
            t1.P1 
= 1;
            t1.P2.Add(
1);
            t1.P2.Add(
2);

            
//序列化
            
//可以把序列化后的xml拿到c++去反序列化。
            XmlSerializer xs = new XmlSerializer(typeof(TestClass));
            StringWriter sw 
= new StringWriter();
            xs.Serialize(sw, t1);
            
string xml = sw.ToString();

            
//反序列化
            
//这里可以把C++序列化后的字符串放到xml里。
            TestClass t2;
            var reader 
= new StringReader(xml);
            t2 
= (TestClass)xs.Deserialize(reader);

        }

    }

C++部分:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
#pragma once
#include 
"stdafx.h"
#include 
"Markup.h"
#include 
"string.h"
#include 
"string"
#include 
<list>
using namespace std;

//Xml序列化基类,要序列化的对象需要继承该类。
//目前支持的字段类型为:字符串,字符串列表,对象,对象列表。
class XmlSerialize
ExpandedBlockStart.gifContractedBlock.gif
{
public:
    
//序列化
    CString Serialize();
    
//反序列化
    void Deserialize(CString& xmlStr);
protected:
    
//处理字符串。
    void Set(CString& name, CString& _value);
    
//处理字对象。
    void Set(CString& name, XmlSerialize& obj);
    
//处理对象列表。
    void Set(CString& listName, CList<CString, CString&>& list);
    
//下面3个模板方法放在头文件里,否则编译器优化的关系,导致出现问题。
    
//处理对象列表。
    template<class T> void Set(CString& listName, CList<T, T&>& list)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
if (isAdd)
            Add(listName, list);
        
else
            Get(list);
    }
;

private:
    
//虚方法,该方法由子类实现把字段添加到Xml,注意:处理字段的顺序要一致。
    virtual void GetInfo() = 0;
    
//虚方法,该方法由子类实现返回类名。
    virtual CString GetClassName() = 0;
    
//内部Xml指示器。
    CMarkup _xml;
    
//指示当前是序列化还是反序列化。
    bool isAdd;
    
//当一个类在内部时用的内部序列化方法。
    CMarkup InnerSerialize(CString& objName, CMarkup& xml);
    CMarkup InnerSerialize(CMarkup
& xml);
    
//添加Xml表头。
    void AddHeader();
    
//添加类名到Xml。
    void AddClassName(CString& className);
    
//开始读取时初始化Xml指示器的位置。
    void GetHeader(CString& xmlStr);
    
//添加字符串。
    void Add(CString& name, CString& _value);
    
//添加对象。
    void Add(CString& name, XmlSerialize& obj);
    
//添加字符串列表。
    void Add(CString& listName, CList<CString, CString&>& list);
    
//读取字符串。
    void Get(CString& _value);
    
//读取对象
    void Get(XmlSerialize& obj);
    
//读取字符串列表。
    void Get(CList<CString,CString&>& list);
    
//添加对象列表。
    template<class T> void Add(CString& listName, CList<T, T&>& list) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        _xml.AddElem(LPCTSTR(listName));
        _xml.IntoElem();
        POSITION pos 
= list.GetHeadPosition();   
        
while(pos != NULL)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            T item 
= list.GetNext(pos);
            XmlSerialize
* sb = &item;
            _xml 
= sb->InnerSerialize(_xml);
        }

        _xml.OutOfElem();
    }
;
    
//读取对象列表。
    template<class T> void Get(CList<T, T&>& list)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{    
        _xml.FindElem();
        _xml.IntoElem();
        
while(_xml.FindElem())
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            T item;
            XmlSerialize
* sb = &item;
            CString s 
= _xml.GetSubDoc();
            sb
->Deserialize(_xml.GetSubDoc());
            list.AddTail(item);
        }

        _xml.OutOfElem();
    }
;
}
;


ContractedBlock.gif ExpandedBlockStart.gif Code
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
ExpandedBlockStart.gifContractedBlock.gif
{
    
//实例化一个将被序列化的类。
    TestClass t1;
    t1.P1 
= "this is a string";
    t1.P2.AddTail(CString(
"string list 1"));
    t1.P2.AddTail(CString(
"string list 2"));
    t1.P3.P1 
= "object";
    MidClass m1;
    MidClass m2;
    m1.P1 
= "object list 1";
    m2.P1 
= "object list 2";
    t1.P4.AddTail(m1);
    t1.P4.AddTail(m2);

    
//序列化。
    
//可以把序列化后的xml拿到c#反序列化。
    CString xml = t1.Serialize();
    
    
//反序列化,可以输入一个由C#对象序列化后的xml,
    
//注意C#对象字段不能为null,如果是能为null的字段(如string),请初始化为空串。
    TestClass t2;
    t2.Deserialize(xml);

    
return 0;
}
 
 
 
 

转载于:https://www.cnblogs.com/ShadowK/archive/2009/01/08/1372099.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值