如何从Memory<byte>中读取一个结构体?

5
能否从 Memory<byte> 创建一个 struct 而不必将其复制到数组中?或者更好的方法是创建一个共享相同托管内存的 structMemory<byte>从字节数组中读取 C/C++ 数据结构的方法在 C# 中几乎可行,但不完全适用。 Memory<T> 有一个 Pin 方法,但它返回一个 MemoryHandle 而不是一个 GCHandle

XY: 我从套接字读取和写入 Memory<byte>,使用从切片获取的范围上的 BinaryPrimitives 来获取和设置各个字段。将 Memory 表示为 struct 将更加美观。

你可以使用 MemoryMarshall.CastSpan<byte> 转换为 Span<struct> 而无需复制字节 - 至少,我认为这是目前语法(非常文档化不好)。 - NetMage
在C#中手动操纵内存是极不寻常的。您通常尽可能避免这种操作,当特定接口强制你使用时,你会立即将其转换为更典型的数据类型进行处理。看起来您正在违反这些规范,但您对此的辩解很差。特别是,我不明白为什么您不直接向套接字写一些 byte[] 而是操纵内存。也不清楚您是否真正执行了我提到的转换,这使人怀疑C#是否是您问题的好语言。 - jpmc26
1
@jpmc26 我不确定这是否很不寻常。.NET Core开发人员显然决定使用Memory<byte>而不是byte[]作为缓冲区与SocketAsyncEventArgs一起工作的首选方式。此处讨论的API(https://github.com/dotnet/corefx/issues/17281)存在于2.2中,尽管它没有记录。实际上,`SetBuffer`的几个未记录重载将其参数转换为`Memory<byte>并设置MemoryBuffer属性,而不是旧的Buffer`属性。 - StackOverthrow
通常而言,Memory<byte>Span<byte>更易于处理。整个标准API似乎都倾向于优先使用它们而不是byte[],只是文档没有跟上。 - StackOverthrow
1个回答

6
.Net Core / .Net Standard 2.1 支持使用MemoryMarshal.Cast<TFrom, TTo>Span<TFrom>进行重新解释转换到一个Span<TTo>。您可以使用Memory<T>.Span属性获取一个Span,然后将其转换为您的struct

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接