首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 結構體序列化與反序列化實作:StructLayout、MarshalAs、Marshal.Copy 進行記憶體區塊轉換

     編輯:關於C語言

結構體定義與屬性


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
public struct Data
{
    public int MessageID;
    public double Price;
    public long Number;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    public string Str;
}
  • LayoutKind.Sequential:依宣告順序緊密排列。
  • Pack = 1:1 位元組對齊,無填充。
  • MarshalAs(ByValTStr, SizeConst=20):固定長度 20 字元 ANSI 字串。

序列化:結構體 → 位元組陣列


public byte[] RawSerialize(object obj)
{
    int size = Marshal.SizeOf(obj);
    IntPtr ptr = Marshal.AllocHGlobal(size);
    Marshal.StructureToPtr(obj, ptr, false);
    byte[] bytes = new byte[size];
    Marshal.Copy(ptr, bytes, 0, size);
    Marshal.FreeHGlobal(ptr);
    return bytes;
}

反序列化:位元組陣列 → 結構體


public Data RawDeserialize(byte[] bytes)
{
    int size = Marshal.SizeOf(typeof(Data));
    if (size > bytes.Length) return new Data();
    IntPtr ptr = Marshal.AllocHGlobal(size);
    Marshal.Copy(bytes, 0, ptr, size);
    object obj = Marshal.PtrToStructure(ptr, typeof(Data));
    Marshal.FreeHGlobal(ptr);
    return (Data)obj;
}

應用範例:共享記憶體讀寫


private void btnTest_Click(object sender, EventArgs e)
{
    var item = new Data { MessageID = 1, Number = 100, Price = 1.2, Str = "ABCD" };
    byte[] data = RawSerialize(item);
    MemDB.Write(data, data.Length); // 寫入共享記憶體
}

private void ReadStruct()
{
    byte[] data = new byte[MemDB.GetLength()];
    MemDB.Read(ref data);
    var item = RawDeserialize(data);
    MessageBox.Show($"{item.MessageID},{item.Number},{item.Price},{item.Str}");
}

此技術常用於高效能進程間通訊、硬體介面資料交換。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved