gpt4 book ai didi

c# - 用于 C# 中结构的字节序列化的字节

转载 作者:太空狗 更新时间:2023-10-29 17:33:06 24 4
gpt4 key购买 nike

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

但是,运行 TestSerialization() 会返回一个 382 字节长的缓冲区(没有预期的内容)!它应该包含 6 个字节。是否可以在不手动序列化的情况下正确序列化这些数据?

最佳答案

只需使用这两种方法:

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):

[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# - 用于 C# 中结构的字节序列化的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/628843/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com