ネットワーク経由でデータを送信したり、バイナリ ファイルにデータを保存したりする場合、多くの場合、構造をバイト配列に変換する必要があります。構造体は複数の関連データ要素を含む値型であり、バイト配列はバイナリ データの連続ブロックです。
CIFS (Common Internet File System) パケットを表す次の C# 構造について考えてみましょう:
<code class="language-csharp">public struct CIFSPacket { // ... various fields ... public string Buffer; }</code>
構造体をバイト配列に変換するには、Marshal クラスの StructToPtr メソッドを使用できます。このメソッドは 2 つのパラメータを受け入れます:
次は、CIFSPacket 構造体をバイト配列に変換する関数です。
<code class="language-csharp">public static byte[] getBytes(CIFSPacket str) { int size = Marshal.SizeOf(str); byte[] arr = new byte[size]; IntPtr ptr = IntPtr.Zero; try { ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(str, ptr, true); Marshal.Copy(ptr, arr, 0, size); } finally { Marshal.FreeHGlobal(ptr); } return arr; }</code>
文字列を正しくマーシャルするには、MarshalAs 属性を使用する必要があります。たとえば、Buffer フィールドが文字列の場合、次のように注釈を付けることができます:
<code class="language-csharp">[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)] public string Buffer;</code>
この属性は、文字列を最大 100 文字の固定長の null で終わる文字列にマーシャリングする必要があることを示します。
構造体のバイト配列表現を取得したら、Marshal クラスの PtrToStructure メソッドを使用して構造体を復元できます。このメソッドは 2 つのパラメータを受け入れます:
以下は、バイト配列を CIFSPacket 構造に変換する関数です:
<code class="language-csharp">public static CIFSPacket fromBytes(byte[] arr) { CIFSPacket str = new CIFSPacket(); int size = Marshal.SizeOf(str); IntPtr ptr = IntPtr.Zero; try { ptr = Marshal.AllocHGlobal(size); Marshal.Copy(arr, 0, ptr, size); str = (CIFSPacket)Marshal.PtrToStructure(ptr, str.GetType()); } finally { Marshal.FreeHGlobal(ptr); } return str; }</code>
これらの関数を使用するには、単に CIFSPacket 構造体を getBytes 関数に渡して、そのバイト配列表現を取得します。あるいは、バイト配列を fromBytes 関数に渡して、元の構造を再作成することもできます。
マーシャリング テクノロジーを活用することで、構造体をバイト配列に簡単に変換したり、逆に変換したりできるため、効率的なデータ送信とストレージが可能になります。
以上がマーシャリングを使用して C# 構造体とバイト配列を相互に変換する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。