C#中有一種方法可以將結構序列化爲二進制流(MemoryStream),以便二進制表示等同於結構在視覺上是如何佈局的(即無填充)?以二進制序列化結構,壓縮格式
在C/C++中,您可以使用#pragma命令來告訴編譯器打包結構,以便字段之間沒有填充。如果您有兩個應用程序通過套接字來回傳遞消息,這會很有幫助。在封裝禁用的情況下,您可以簡單地將結構的內容「發送」到套接字上,而不必擔心將每個字段單獨封裝到二進制緩衝區中(還必須在必要時進行字節順序交換)。
C#中有一種方法可以將結構序列化爲二進制流(MemoryStream),以便二進制表示等同於結構在視覺上是如何佈局的(即無填充)?以二進制序列化結構,壓縮格式
在C/C++中,您可以使用#pragma命令來告訴編譯器打包結構,以便字段之間沒有填充。如果您有兩個應用程序通過套接字來回傳遞消息,這會很有幫助。在封裝禁用的情況下,您可以簡單地將結構的內容「發送」到套接字上,而不必擔心將每個字段單獨封裝到二進制緩衝區中(還必須在必要時進行字節順序交換)。
除非您使用不安全的代碼,否則不會。使用Protocol Buffers或Thrift或類似的東西;根據我的經驗,我不會推薦.NET內置二進制序列化。您也可以使用BinaryWriter/BinaryReader
(使用反射或預生成序列化代碼)來序列化/反序列化。至於包裝,您可以使用[StructLayout]
屬性來控制它。
您可以使用[StructLayout]
和[FieldOffset]
屬性來控制你的結構的域被打包的方式(谷歌「編組」獲取更多信息),然後使用以下方法來生成你的結構的二進制表示,可以通過發送您網絡流:
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;
}
的缺點:
對於信息 - protobuf網不支持結構(只有類),和我很確定dotnet-protobufs也不是。我不知道節儉。 – 2009-05-03 19:02:04