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

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

我正在寻找 C# 中序列化的语言支持.我可以从 ISerializable 派生并通过复制字节缓冲区中的成员值来实现序列化.但是,我更喜欢一种更自动化的方式,就像在 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++.

考虑以下代码:

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; } } }

我有一个通用的 Frame 结构,它充当多种类型的有效载荷的包装器,用于串行传输.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; }

现在您可以使用

StructTools.RawDeserialize<MyStructType>(byteArray, 0); // 0 is offset in byte[]

并使用

StructTools.RawSerialize(myStruct);

更多推荐

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

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

发布评论

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

>www.elefans.com

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