最近项目需要,为了解决C++和C#之间Socket通信。能够传对象。
写了个C++序列化的功能主要是兼容C#序列化的格式,这样用C++序列化的xml,可以用C#反序列化回来,反之同理。
不敢藏起来,拿出来同大家分享。
最近项目需要,为了解决C++和C#之间Socket通信,能够传对象。
写了个C++序列化的功能主要是兼容C#序列化的格式,这样用C++序列化的xml,可以用C#反序列化回来,反之同理。
不敢藏起来,拿出来同大家分享。
话不多说,直接上代码。https://files.cnblogs.com/ShadowK/seri.rar
C#部分。
Code
/**//// <summary>
/// 对应C++版本相同的类。C++版本字段只能CString类型。
/// C#可以为string, int, enum, float,
/// DataTime(C++赋值的时候要符合格式"2008-11-06T01:01:01")
/// 其它的没有试过。应该都可以。
/// </summary>
public class MidClass
{
public string P1;
}
public class TestClass
{
public int P1;
public List<int> P2 = new List<int>();
public MidClass P3;
public List<MidClass> P4;
}
class Program
{
static void Main(string[] args)
{
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);
}
}
/**//// <summary>
/// 对应C++版本相同的类。C++版本字段只能CString类型。
/// C#可以为string, int, enum, float,
/// DataTime(C++赋值的时候要符合格式"2008-11-06T01:01:01")
/// 其它的没有试过。应该都可以。
/// </summary>
public class MidClass
{
public string P1;
}
public class TestClass
{
public int P1;
public List<int> P2 = new List<int>();
public MidClass P3;
public List<MidClass> P4;
}
class Program
{
static void Main(string[] args)
{
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++部分:
Code
#pragma once
#include "stdafx.h"
#include "Markup.h"
#include "string.h"
#include "string"
#include <list>
using namespace std;
//Xml序列化基类,要序列化的对象需要继承该类。
//目前支持的字段类型为:字符串,字符串列表,对象,对象列表。
class XmlSerialize
{
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)
{
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)
{
_xml.AddElem(LPCTSTR(listName));
_xml.IntoElem();
POSITION pos = list.GetHeadPosition();
while(pos != NULL)
{
T item = list.GetNext(pos);
XmlSerialize* sb = &item;
_xml = sb->InnerSerialize(_xml);
}
_xml.OutOfElem();
};
//读取对象列表。
template<class T> void Get(CList<T, T&>& list)
{
_xml.FindElem();
_xml.IntoElem();
while(_xml.FindElem())
{
T item;
XmlSerialize* sb = &item;
CString s = _xml.GetSubDoc();
sb->Deserialize(_xml.GetSubDoc());
list.AddTail(item);
}
_xml.OutOfElem();
};
};
#pragma once
#include "stdafx.h"
#include "Markup.h"
#include "string.h"
#include "string"
#include <list>
using namespace std;
//Xml序列化基类,要序列化的对象需要继承该类。
//目前支持的字段类型为:字符串,字符串列表,对象,对象列表。
class XmlSerialize
{
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)
{
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)
{
_xml.AddElem(LPCTSTR(listName));
_xml.IntoElem();
POSITION pos = list.GetHeadPosition();
while(pos != NULL)
{
T item = list.GetNext(pos);
XmlSerialize* sb = &item;
_xml = sb->InnerSerialize(_xml);
}
_xml.OutOfElem();
};
//读取对象列表。
template<class T> void Get(CList<T, T&>& list)
{
_xml.FindElem();
_xml.IntoElem();
while(_xml.FindElem())
{
T item;
XmlSerialize* sb = &item;
CString s = _xml.GetSubDoc();
sb->Deserialize(_xml.GetSubDoc());
list.AddTail(item);
}
_xml.OutOfElem();
};
};
Code
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
//实例化一个将被序列化的类。
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;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
//实例化一个将被序列化的类。
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;
}