为 Memory<byte> / Span<byte> 获取可变结构的正确方法?
Proper way to get a mutable struct for Memory<byte> / Span<byte>?
对于网络协议实现,我想利用新的 Memory
和 Span
类 在通过 [= 访问数据时实现缓冲区的零拷贝15=].
我有以下人为的例子:
[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
(不能用作泛型类型参数)一起使用或如何获取实际缓冲区中的结构而不是一个副本(在其上所做的任何突变都不会反映在缓冲区中)。
有没有更简单的方法从缓冲区中获取这个可变结构?
哎呀。看起来 MemoryMarshal.Cast
曾经是 NonPortableCast
扩展方法(来自:this commit),在这种情况下 - 是的,这是在 span 布局之间进行 thunk 的合适方式,最常见(但不完全)就像在这种情况下 - 在 byte
和一些 struct
.
之间
对于网络协议实现,我想利用新的 Memory
和 Span
类 在通过 [= 访问数据时实现缓冲区的零拷贝15=].
我有以下人为的例子:
[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
(不能用作泛型类型参数)一起使用或如何获取实际缓冲区中的结构而不是一个副本(在其上所做的任何突变都不会反映在缓冲区中)。
有没有更简单的方法从缓冲区中获取这个可变结构?
哎呀。看起来 MemoryMarshal.Cast
曾经是 NonPortableCast
扩展方法(来自:this commit),在这种情况下 - 是的,这是在 span 布局之间进行 thunk 的合适方式,最常见(但不完全)就像在这种情况下 - 在 byte
和一些 struct
.