哪位高手可以给我写个简单的例子,应用下面这段代码 完成Struct 和 BYTE []之间的转换 C#中将自定义的structure转换为byte[]
在Socket编程中经常会碰到将Struct转换为byte数组进行传送的情况. 如果服务器和客户端都是自己开发的话, 用序列化和反序列化当然会比较简单, 但序列化后会数据里会包含一些额外的数据,如:程序集名称、版本、公钥等, 不适用于一端是非托管程序. 在.NET Framework的System.Runtime.InteropServices.Marshal类中包含两个方法可以解决此问题:
StructureToPtr 方法: 将数据从托管对象封送到非托管内存块;
PtrToStructure 方法: 将数据从非托管内存块封送到托管对象。
用以下代码就可以实现struct与byte[]之间的相互转换:
using System.Runtime.InteropServices; public static byte[] RawSerialize( object anything ) { int rawsize = Marshal.SizeOf( anything ); IntPtr buffer = Marshal.AllocHGlobal( rawsize ); Marshal.StructureToPtr( anything, buffer, false ); byte[] rawdatas = new byte[ rawsize ]; Marshal.Copy( buffer, rawdatas, 0, rawsize ); Marshal.FreeHGlobal( buffer ); return rawdatas; }
public static object RawDeserialize( byte[] rawdatas, Type anytype ) { int rawsize = Marshal.SizeOf( anytype ); if( rawsize > rawdatas.Length ) return null; IntPtr buffer = Marshal.AllocHGlobal( rawsize ); Marshal.Copy( rawdatas, 0, buffer, rawsize ); object retobj = Marshal.PtrToStructure( buffer, anytype ); Marshal.FreeHGlobal( buffer ); return retobj; }
在Socket编程中经常会碰到将Struct转换为byte数组进行传送的情况. 如果服务器和客户端都是自己开发的话, 用序列化和反序列化当然会比较简单, 但序列化后会数据里会包含一些额外的数据,如:程序集名称、版本、公钥等, 不适用于一端是非托管程序. 在.NET Framework的System.Runtime.InteropServices.Marshal类中包含两个方法可以解决此问题:
StructureToPtr 方法: 将数据从托管对象封送到非托管内存块;
PtrToStructure 方法: 将数据从非托管内存块封送到托管对象。
用以下代码就可以实现struct与byte[]之间的相互转换:
using System.Runtime.InteropServices; public static byte[] RawSerialize( object anything ) { int rawsize = Marshal.SizeOf( anything ); IntPtr buffer = Marshal.AllocHGlobal( rawsize ); Marshal.StructureToPtr( anything, buffer, false ); byte[] rawdatas = new byte[ rawsize ]; Marshal.Copy( buffer, rawdatas, 0, rawsize ); Marshal.FreeHGlobal( buffer ); return rawdatas; }
public static object RawDeserialize( byte[] rawdatas, Type anytype ) { int rawsize = Marshal.SizeOf( anytype ); if( rawsize > rawdatas.Length ) return null; IntPtr buffer = Marshal.AllocHGlobal( rawsize ); Marshal.Copy( rawdatas, 0, buffer, rawsize ); object retobj = Marshal.PtrToStructure( buffer, anytype ); Marshal.FreeHGlobal( buffer ); return retobj; }
{
[类型号(属性名)10位] [长度 10位] [属性名]
[类型号(属性类型) 10位] [长度 10位] [属性值] ps:如不是值属性,继续递归分解
}所有的拼接在一起形成一个字符串 ==> byte[]
具体代码请稍侯...
public class A
{
public enum SerializeObjectType : int
{
String = 1,
Int32 = 2
} public string Serialize(object data)
{
StringBuilder serializeString = new StringBuilder(); try
{
Type type = data.GetType();
foreach (FieldInfo field in type.GetFields())
{
object newValue = field.GetValue(data);
if (newValue != null)
{
serializeString.Append(SerializeObject(field.Name));
serializeString.Append(SerializeObject(newValue));
}
} return serializeString.ToString();
}
catch
{
return "";
}
} /// <summary>
/// 序列化单个对象 格式:[类型 10位] [值长度 10位] [值]
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private string SerializeObject(object obj)
{
if (obj is string)
{
return FillString(((int)SerializeObjectType.String).ToString()) + FillString(obj.ToString().Length.ToString()) + obj.ToString();
}
else if (obj is int)
{
return FillString(((int)SerializeObjectType.Int32).ToString()) + FillString(obj.ToString().Length.ToString()) + obj.ToString();
}
//else if & else if & ...
else
{
return "";
}
} private string FillString(string s)
{
for (int i = s.Length; i < 10; i++)
{
s = "0" + s;
}
return s;
}
}