字节在C#中的结构的字节序列化

编程入门 行业动态 更新时间:2024-10-26 06:37:28
本文介绍了字节在C#中的结构的字节序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我在寻找的语言支持序列化在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#中的结构的字节序列化

本文发布于:2023-11-10 01:16:14,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1573958.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:字节   结构   序列化

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!