获取 Memory<byte> / Span<byte> 的可变结构的正确方法是什么?

5

我想要利用新的MemorySpan类来实现对缓冲区的零拷贝,并通过struct访问数据,以用于网络协议的实现。

我有以下人为示例:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Data
{
    public int IntValue;
    public short ShortValue;
    public byte ByteValue;
}

static void Prepare()
{
    var buffer = new byte[1024];
    var dSpan = MemoryMarshal.Cast<byte, Data>(buffer);
    ref var d = ref dSpan[0];

    d.ByteValue = 1;
    d.ShortValue = (2 << 8) + 3;
    d.IntValue = (4 << 24) + (5 << 16) + (6 << 8) + 7;
}

结果是buffer中存储了7,6,5,4,3,2,1,这正是所需的,但我几乎无法想象MemoryMarshal.Cast是唯一的方法(除了任何需要unsafe关键字的方法)。我尝试了其他一些方法,但我无法弄清如何将它们与ref struct(不能用作通用类型参数)一起使用,也不知道如何获取实际缓冲区中的结构体而不是副本(对其进行的任何更改都不会反映在缓冲区中)。
是否有更简单的方法从缓冲区获取此可变结构体?

C++ 经常与 C# 一起使用,并且可以兼容。 - jdweng
1
@jdweng,你是在谈论manager C++还是native C++?你能提供至少一个“许多Net Library方法”中的示例吗?我看过许多第三方库的源代码,但从未见过其中使用C++。 - mycroes
什么是托管C++?有MSDN C++和本机C++。微软喜欢发明自己的世界。 - jdweng
1
@jdweng 管理的 C++:(https://en.wikipedia.org/wiki/Managed_Extensions_for_C%2B%2B)能否请您提供一个可用的答案(作为实际答案),或者将此问题保留不变。 - mycroes
4
Span<T>的一个关键点是,不再需要使用unsafe或C++来利用这种100%托管/“安全”的内存使用。 - Marc Gravell
显示剩余5条评论
1个回答

5

哎呀。看起来MemoryMarshal.Cast就是以前的NonPortableCast扩展方法(来源:此提交),在这种情况下 - 是的,这是在跨度布局之间进行Thunk的适当方式,最常见的是(但不仅限于)像这种情况 - 在byte和某些struct之间。


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