c#構造体とbyte[]間の変換

2273 ワード

    /// 
    ///  byte[]
    /// 
    /// 
    /// 
    public static Byte[] StructToBytes(Object structure)
    {
        Int32 size = Marshal.SizeOf(structure);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        try
        {
            Marshal.StructureToPtr(structure, buffer, false);
            Byte[] bytes = new Byte[size];
            Marshal.Copy(buffer, bytes, 0, size);

            return bytes;
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }
    }
    /// 
    /// byte[] 
    /// 
    /// 
    /// 
    /// 
    public static Object BytesToStruct(Byte[] bytes, Type strcutType)
    {
        Int32 size = Marshal.SizeOf(strcutType);
        IntPtr buffer = Marshal.AllocHGlobal(size);
        try
        {
            Marshal.Copy(bytes, 0, buffer, size);

            return Marshal.PtrToStructure(buffer, strcutType);
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }
    }

この2つの関数はbyte[]配列と構造体との間の変換を実現した.構造体は、通信時に直接送信および受信することができる.以下のように、PlatCellMsg pcm=(PlatCellMsg)BytesToStruct(buf,typeof(PlatCellMsg);byte[] s = StructToBytes(pcm ); ただし、構造体を定義するには、2つの点に注意する必要があります.
  • 構造体に固定長の文字列またはbyteがある場合:MarshalAsを使用する必要がある;以下のpublic struct PlatCellMsg{[MarshalAs(UnmanagedType.ByValArray,SizeConst=32)]public char[]fDevName;public short fcams;public short fIOin;public short fIOOut;private short Fwuyong;public int fSubCells;public int fCellId;}ここでfDevNameは32バイトのchar[]と定義されています.
  • で定義構造体の長さは、上記のように構造体が32+2+2+2+2+4+4=48バイトを占め、対応するbyte[]の長さも48であるべきである.しかし、上記のような構造体は、その長さが52:public struct PlatCellMsg{[MarshalAs(UnmanagedType.ByValArray,SizeConst=32)]public char[]fDevName;public short fcams;public short fIOin;public short fIOOut;public int fSubCells;public int fCellId;private short Fwuyong;順番を変えただけです.しかし、その長さは本当に52になっていて、なぜか分かりませんが、推測すると、32ビットアプリケーションぐらいで、一度は4バイトを処理して下の構造体を処理するときは次のように計算します.32+(2+2)+(2+2)+4+4+(2+2)=52のうち、この2つは前のデータを処理するときに余裕があるためですが、後のデータを一緒に処理することができず、2バイト多く占めています.ははははコンピュータを習ったことがないので、このように理解しました.最後に参照を追加する必要があります:using System.Runtime.InteropServices;