首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以安全地序列化非托管类型?

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

Stack Overflow用户
提问于 2022-06-25 11:09:51
回答 1查看 80关注 0票数 3

当我发现unmanaged泛型约束时,我非常兴奋,因为我认为这将解决我的序列化需求。但是,阅读更多关于它的信息,似乎使用约束进行序列化并不是一个好主意。

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

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

阅读同样简单:

代码语言:javascript
复制
public unsafe T Read<T>(int offset) where T : unmanaged
{
    fixed (byte* pointer = &Bytes[offset])
    {
        return *(T*) pointer;
    }
}

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

但像往常一样,当某件事看起来太好而不是真的时,通常是这样的。第一个问题是,如果两个系统使用不同的endianness,这些方法就无法工作。例如,system 1写入一个整数,通过网络发送它,系统2(具有不同的endianness)尝试读取它。系统2将解释一个错误的值。

第二个潜在问题是结构布局,不同的平台可能有不同的结构内存布局,因此我们有与endianness相同的问题。

这让我怀疑,在所有平台上都能工作的通用序列化,无论是endianness还是struct布局,是否都是可能的。如果是这样的话,我很想看看解决办法。或者是最好的(也是唯一的)解决方案,分别为每种类型编写序列化方法,如BitConverterBinaryWriterBinaryReader和相对较新的BinaryPrimitives

EN

回答 1

Stack Overflow用户

发布于 2022-06-25 14:27:45

是的,如果您小心的话,您可以使用这个特性在某些情况下加快代码的速度。

  1. 布局。--我不会说这是个问题。网络协议应该明确定义数据格式。然后使用[StructLayout(LayoutKind.Sequential, Pack=...)] (或其他语言中的等效语言)实现相应的类型。
  2. endianness. ,网络协议具有特定的endianness.如果协议endianness与当前硬件endianness相匹配,则可以使用问题中描述的直接复制方法。否则,我们应该单独编写字段,反转字节顺序(使用BinaryPrimitives.ReverseEndianness)。

作为自定义二进制协议的维护者,我建议您不要发明自己的协议。这很难,而且容易出错。

就拿阿夫罗MessagePack来说吧--它们太棒了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72753361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档