2006年10月20日

C#の構造体をbyte配列に  

   このエントリーをはてなブックマークに追加 mixiチェック Clip to Evernote
例えば
 [StructLayout(LayoutKind.Sequential)]
struct MyRecord {
public int number1;
public ushort number2;
public ushort number3;
}

のような構造体があった時に、この内容をbyte配列に変換したいのだが、unsafeなコードを使わないで、これを実現する方法ってあるんだろうか?
C言語だったら、char型のポインタへキャストして、memcpyして終わりなんだけれど、C#でこれを安全にやる方法ってのがよくわからない。
シリアライズとか使えればいいんだけれど、今回は事情があって使えない。

いろいろ、悩んだ結果、BitConverterクラスで一つ一つ変換することにした。
  byte[] bytes = BitConverter.GetBytes(rec.number1);
Array.Copy(buffer, 0, bytes, 0, bytes.Length);
...

うーん、かなり力技だけどまあいいか。

この記事へのコメント
ちょっと手数多いけど、Marshal.StructureToPtr() して Marshal.ReadByte() とか。

Posted by 渋木宏明(ひどり) at 2006年10月24日 11:22
なるほど、これならば、BitConverterよりも汎用的に使えるコードが書けそうです。これから試してみます。
どうもありがとうございます。
Posted by Gushwell at 2006年10月24日 18:41
Marshal.ReadByte() じゃなくて Marshal.Copy() の方がよさそうですね。
Posted by 渋木宏明(ひどり) at 2006年10月27日 00:56
ですね。ループが不要になりますので。

こんな感じでしょうか。

MyStruct o = new MyStruct();
...
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(o));
try {
Marshal.StructureToPtr(o, ptr, false);
byte[] bytes = new byte[Marshal.SizeOf(o)];
Marshal.Copy(ptr, bytes, 0, Marshal.SizeOf(o));
...
} finally {
Marshal.FreeHGlobal(ptr);
}

どうもありがとうございました。
Posted by Gushwell at 2006年10月27日 09:45
 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/50618358