2009-05-03 17 views
2

構造体を視覚的にレイアウトする方法(すなわちパディングなし)と同じように、バイナリストリーム(MemoryStream)に構造体をシリアル化する方法はありますか?バイナリ、パック形式の構造体をシリアル化

C/C++では、#pragmaコマンドを使用して、フィールド間にパディングがないように構造体をパックするようにコンパイラに指示します。これは、2つのアプリケーションがソケットを介してメッセージを渡す場合に役立ちます。パッキングを無効にすると、ソケットの構造体の内容を単純に "送信"でき、各フィールドをバイナリバッファに個別にパックすることを心配する必要はありません(必要に応じてエンディアンスワッピングを行う必要があります)。

答えて

2

安全でないコードを使用している場合を除きます。プロトコルバッファやスリフトなどを使用してください。私は.NETの組み込みバイナリシリアル化を私の経験に基づいてお勧めしません。 BinaryWriter/BinaryReaderでシリアル化/逆シリアル化することもできます(リフレクションを使用するか、シリアライゼーションコードを事前生成する)。パッキングに関しては、[StructLayout]属性で制御することができます。

+0

を持つことはできません - いるProtobuf-netは構造体(クラスのみ)、およびIをサポートしていません。かなり確実なdotnet-protobufsもありません。私は倹約について知りません。 –

1

[StructLayout][FieldOffset]属性を使用して、構造体のフィールドのパック方法(詳細についてはGoogleの「マーシャリング」)を制御し、次のコードを使用して構造体のバイナリ表現を生成し、ネットワークストリーム:

public static byte[] GetBytes<TStruct>(TStruct data) where TStruct : struct 
{ 
    int structSize = Marshal.SizeOf(typeof(TStruct)); 
    byte[] buffer = new byte[structSize]; 
    GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); 
    Marshal.StructureToPtr(data, handle.AddrOfPinnedObject(), false); 
    handle.Free(); 
    return buffer; 
} 

欠点:

  • そのない慣用.NET
  • あなたが必要アンマネージコードの権限
  • バッファピニングは、パフォーマンスに影響を与える可能性がある
  • あなたの構造は、情報の参照(文字列や配列のための特別な場合がある)
関連する問題