最近在使用結構體與字節數組轉化來實現socket間數據傳輸。現在開始整理一下。對於Marshal可以查閱msdn,關於字節數組與結構體轉代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
namespace FileSendClient
{
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
struct StructDemo
{
public byte a;
public byte c;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] b;
public byte d;
public int e;
}
unsafe class Program
{
static void Main(string[] args)
{
StructDemo sd;
sd.a = 0;
sd.d = 0;
sd.c = 0;
sd.b = new byte[3] { 0, 0, 1 };
sd.e = 5;
int size = 0;
//此處使用非安全代碼來獲取到StructDemo的值
unsafe
{
size = Marshal.SizeOf(sd);
}
byte[] b = StructToBytes(sd,size);
ByteToStruct(b, typeof(StructDemo));
}
//將Byte轉換為結構體類型
public static byte[] StructToBytes(object structObj,int size)
{
StructDemo sd;
int num = 2;
byte[] bytes = new byte[size];
IntPtr structPtr = Marshal.AllocHGlobal(size);
//將結構體拷到分配好的內存空間
Marshal.StructureToPtr(structObj, structPtr, false);
//從內存空間拷貝到byte 數組
Marshal.Copy(structPtr, bytes, 0, size);
//釋放內存空間
Marshal.FreeHGlobal(structPtr);
return bytes;
}
//將Byte轉換為結構體類型
public static object ByteToStruct(byte[] bytes, Type type)
{
int size = Marshal.SizeOf(type);
if (size > bytes.Length)
{
return null;
}
//分配結構體內存空間
IntPtr structPtr = Marshal.AllocHGlobal(size);
//將byte數組拷貝到分配好的內存空間
Marshal.Copy(bytes, 0, structPtr, size);
//將內存空間轉換為目標結構體
object obj = Marshal.PtrToStructure(structPtr, type);
//釋放內存空間
Marshal.FreeHGlobal(structPtr);
return obj;
}
}
}
