我在寻找的语言支持序列化在C#。我可以从ISerializable的派生,并通过在一个字节的缓冲区复制成员值实现序列化。不过,我想preFER更自动的方式就像人们可以在C / C ++做
I'm looking for language support of serialization in C#. I could derive from ISerializable and implement the serialization by copying member values in a byte buffer. However, I would prefer a more automatic way like one could do in C/C++.
考虑以下code:
using System; using System.Text; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.IO; namespace XBeeHelper { class XBee { [Serializable()] public struct Frame<FrameType> where FrameType : struct { public Byte StartDelimiter; public UInt16 Lenght; public Byte APIIdentifier; public FrameType FrameData; public Byte Checksum; } [Serializable()] public struct ModemStatus { public Byte Status; } public Byte[] TestSerialization() { Frame<ModemStatus> frame = new Frame<ModemStatus>(); frame.StartDelimiter = 1; frame.Lenght = 2; frame.APIIdentifier = 3; frame.FrameData.Status = 4; frame.Checksum = 5; BinaryFormatter formatter = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); formatter.Serialize(stream, frame); Byte[] buffer = stream.ToArray(); return buffer; } } }我有一个通用的框架结构充当多种类型的有效载荷,用于串行传输的包装。 ModemStatus是这样的有效负载的一个例子。
I have a generic Frame struct acting as a wrapper for many types of payload, for serial transmission. ModemStatus is an example of such payload.
但是,运行TestSerialization()返回一个缓冲的 382 字节长度(不包括预期的内容)!它应载有6个字节。是否有可能无需手动序列化正确地序列这些数据?
However, running TestSerialization() returns a buffer 382 bytes long (without the expected content)! It should have contained 6 bytes. Is it possible to serialize this data correctly without manual serializing?
推荐答案只需使用此两种方法:
public static class StructTools { /// <summary> /// converts byte[] to struct /// </summary> public static T RawDeserialize<T>(byte[] rawData, int position) { int rawsize = Marshal.SizeOf(typeof(T)); if (rawsize > rawData.Length - position) throw new ArgumentException("Not enough data to fill struct. Array length from position: "+(rawData.Length-position) + ", Struct length: "+rawsize); IntPtr buffer = Marshal.AllocHGlobal(rawsize); Marshal.Copy(rawData, position, buffer, rawsize); T retobj = (T)Marshal.PtrToStructure(buffer, typeof(T)); Marshal.FreeHGlobal(buffer); return retobj; } /// <summary> /// converts a struct to byte[] /// </summary> public static byte[] RawSerialize(object anything) { int rawSize = Marshal.SizeOf(anything); IntPtr buffer = Marshal.AllocHGlobal(rawSize); Marshal.StructureToPtr(anything, buffer, false); byte[] rawDatas = new byte[rawSize]; Marshal.Copy(buffer, rawDatas, 0, rawSize); Marshal.FreeHGlobal(buffer); return rawDatas; } }和指定你的结构是这样的(一个字节指定的确切大小和包装(对齐)默认值为8):
And specify your struct like this (Specify the exact size and pack (align) by one byte. default is 8):
[StructLayout(LayoutKind.Explicit, Size = 11, Pack = 1)] private struct MyStructType { [FieldOffset(0)] public UInt16 Type; [FieldOffset(2)] public Byte DeviceNumber; [FieldOffset(3)] public UInt32 TableVersion; [FieldOffset(7)] public UInt32 SerialNumber; }现在你可以使用反序列化
Now you can Deserialize using
StructTools.RawDeserialize<MyStructType>(byteArray, 0); // 0 is offset in byte[]和序列化使用
StructTools.RawSerialize(myStruct);更多推荐
字节在C#中的结构的字节序列化
发布评论