C#非管理メモリの応用(二)―構造体コピー
3310 ワード
構造体の変換は実は基礎タイプの配列の変換とあまり差がないが、構造体はMarshalを通過できない.Copy方式でメモリに直接変換します.構造体痛byte配列の相互回転は,ネットワーク通信に直接用いるのに非常に便利である.
1、構造体を定義する
2、Copy構造体がbyte配列になる方法
3、byte配列Copyの構造体形成方法
4、試験手順
1、構造体を定義する
/// <summary>
/// Copy
/// </summary>
public struct TestStruct
{
public string Number;
public int[] IntMember;
public byte ByteMember;
public short ShortMember;
public override string ToString()
{
return string.Format("Number:" + Number + " ByteMember:" + ByteMember + " ShortMember:" + ShortMember + " IntMemberCount:" + IntMember.Length);
}
}
2、Copy構造体がbyte配列になる方法
/// <summary>
/// Copy byte
/// </summary>
/// <param name="structObj"> </param>
/// <param name="targetData"> byte , Marshal.SizeOf(structObj)</param>
public static void CopyMemFromStruct(object structObj, byte[] targetData)
{
IntPtr tmptr = IntPtr.Zero;
try
{
int size = Marshal.SizeOf(structObj); //
tmptr = Marshal.AllocHGlobal(size); //
Marshal.StructureToPtr(structObj, tmptr, false); //Copy
Marshal.Copy(tmptr, targetData, 0, size);
Marshal.FreeHGlobal(tmptr);
}
catch(Exception ex)
{
if (tmptr != IntPtr.Zero)
Marshal.FreeHGlobal(tmptr);
throw new Exception(" :" + ex.ToString());
}
}
3、byte配列Copyの構造体形成方法
/// <summary>
/// byte
/// </summary>
/// <param name="sourceData"></param>
/// <param name="startIndex"></param>
/// <param name="length"></param>
/// <param name="objectRef"></param>
/// <param name="type"></param>
public static void CopyMemFromBytes(byte [] sourceData, int startIndex, int length, ref object objectRef, Type type)
{
IntPtr tmptr = IntPtr.Zero;
try
{
tmptr = Marshal.AllocHGlobal(length);
Marshal.Copy(sourceData, startIndex, tmptr, length);
objectRef = Marshal.PtrToStructure(tmptr, type);
Marshal.FreeHGlobal(tmptr);
}
catch (Exception ex)
{
if (tmptr != IntPtr.Zero)
Marshal.FreeHGlobal(tmptr);
throw new Exception(" :" + ex.ToString());
}
}
4、試験手順
TestStruct struct1 = new TestStruct();
struct1.ByteMember = 123;
struct1.IntMember = new int[] { 1, 3, 45, 4 };
struct1.Number = "test";
struct1.ShortMember = 23241;
Console.WriteLine(struct1.ToString());
int size = Marshal.SizeOf(struct1);
byte[] testDest = new byte[size];
MemoryCopy.CopyMemFromStruct(struct1, testDest);
object struct2 = new TestStruct();
MemoryCopy.CopyMemFromBytes(testDest, 0, size,ref struct2, typeof(TestStruct));
Console.WriteLine(struct2.ToString());