gpt4 book ai didi

c# - 是否可以安全地序列化非托管类型?

转载 作者:行者123 更新时间:2023-12-05 05:39:13 24 4
gpt4 key购买 nike

当我发现 unmanaged 时通用约束,我真的很兴奋,因为我认为这会解决我的序列化需求。但是,阅读更多相关信息后,似乎将约束用于序列化目的并不是一个好主意。

对于上下文,我正在创建一个低级网络库,我希望允许用户轻松序列化简单类型,例如基元或枚举。我创建了一个接受任何 unmanaged 的通用方法键入并将其写入字节数组。

public unsafe void Write<T>(T value, int offset) where T : unmanaged
{
fixed (byte* pointer = &Bytes[offset])
{
*(T*) pointer = value;
}
}

阅读就这么简单:

public unsafe T Read<T>(int offset) where T : unmanaged
{
fixed (byte* pointer = &Bytes[offset])
{
return *(T*) pointer;
}
}

乍一看,这些方法非常适合序列化;它们非常快(简单的直接内存写入或读取),它们是通用的(不需要为每个原语编写方法,例如 intfloat 等)它们甚至支持开箱即用的用户定义类型(枚举和自定义 unmanaged 结构)。

但像往常一样,当某件事看起来好得令人难以置信时,它通常就是真的。第一个问题是,如果 2 个系统使用不同的字节顺序,这些方法将不起作用。例如,系统 1 写入一个整数,通过网络发送它,系统 2(具有不同的字节顺序)试图读取它。系统 2 将解释错误的值。

第二个潜在的问题是结构布局,不同的平台可能有不同的结构内存布局,所以我们遇到了与字节顺序相同的问题。

这让我想知道是否可以在所有平台上工作的通用序列化,无论字节顺序或结构布局如何。如果是这样,我很乐意看到解决方案。或者是最好(也是唯一)的解决方案,分别为每种类型编写序列化方法,如 BitConverter 等类中所示。 , BinaryWriter , BinaryReader和相对较新的BinaryPrimitives

最佳答案

是的,如果您小心的话,在某些情况下可以使用此功能来加速代码。

  1. 布局。我不会说这是一个问题。网络协议(protocol)应该明确定义数据格式。然后我们相应地实现类型,使用 [StructLayout(LayoutKind.Sequential, Pack=...)](或其他语言的等价物)。

  2. 字节序。同样,网络协议(protocol)具有特定的字节序。如果协议(protocol)字节序与当前硬件字节序匹配,我们可以使用问题中描述的直接复制方法。否则,我们应该单独编写字段,反转字节顺序(使用 BinaryPrimitives.ReverseEndianness)。

作为 custom binary protocol 的维护者,我建议不要发明自己的协议(protocol)。它很难且容易出错。

就拿AvroMessagePack - 那些很棒。

关于c# - 是否可以安全地序列化非托管类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72753361/

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