構造体をバイト配列として転送することが実際に必要な場合は、次のようなコードを試すこともできます。
int rawsize = Marshal.SizeOf(value);
byte[] rawdata = new byte[rawsize];
GCHandle handle = GCHandle.Alloc(rawdata, GCHandleType.Pinned);
Marshal.StructureToPtr(value, handle.AddrOfPinnedObject(), false);
handle.Free();
これは、指定されたオブジェクト値をバイト配列 rawdata に変換します。これは以前に書いたコードから取ったもので、実際に機能させるには、ニーズに合わせて調整する必要がある場合があります。ユーザー定義の構造体を持つハードウェアとの通信に使用しましたが、組み込み型でも機能するはずです (結局のところ、それらは構造体ですよね?)。
構造体メンバーを適切に整列させるには、StructLayout 属性を使用して one-byte-alignment を指定します。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
次に、インライン配列など、フィールドの必要に応じて MarshalAs 属性を使用します。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
byte[] _state;
バイト配列から構造を取得するコードは、次のようなものです。
public T GetValue<T>()
{
GCHandle handle = GCHandle.Alloc(RawValue, GCHandleType.Pinned);
T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),
typeof(T));
handle.Free();
return structure;
}
もちろん、これを機能させるには、必要なタイプを知る必要があります。
これ自体はエンディアンを処理しないことに注意してください。私のプロジェクトでは、ほとんどのフィールドは 1 バイトのみだったので問題ではありませんでしたが、それがあったいくつかのフィールドについては、フィールドをプライベートにして、エンディアンを処理するパブリック プロパティを追加しました ( Jon Skeet のリンクから彼の答えへのコメントはあなたを助けるかもしれません.私はこれのためにいくつかのユーティリティ関数を書きました.
これが必要なときは、生の値を格納する Message クラスを作成し (したがって、GetValue メソッド、一番上のコードは実際には SetValue メソッドの本体です)、フォーマットされた値を取得するための便利なメソッドをいくつか用意しました。