【问题标题】:Proper way to get a mutable struct for Memory<byte> / Span<byte>?获取 Memory<byte> / Span<byte> 的可变结构的正确方法?
【发布时间】:2018-05-26 20:34:03
【问题描述】:

对于网络协议实现,我想利用新的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;
}

结果是buffer7, 6, 5, 4, 3, 2, 1 填充,这是所希望的,但我很难想象MemoryMarshal.Cast 是唯一的方法(禁止任何需要unsafe 关键字的东西)来执行此操作。我尝试了其他一些方法,但我不知道如何将它们与 ref struct (不能用作泛型类型参数)一起使用,或者如何获取实际缓冲区中的结构而不是副本(在其上所做的任何突变都不会反映在缓冲区中)。

有没有更简单的方法从缓冲区中获取这个可变结构?

【问题讨论】:

  • 那么memory.cast解决方案又出了什么问题?
  • 您总是可以编写 C++ 代码来进行指向,就像在许多网络库方法中所做的那样。
  • @jdweng 你说的是经理 C++ 还是原生 C++?您能否提供至少一个“许多网络库方法”之一的示例?我看过许多第三方库的来源,不记得曾经在其中使用过 C++。
  • @jdweng Managed C++: (en.wikipedia.org/wiki/Managed_Extensions_for_C%2B%2B) 您能否提供一个可用的答案(作为实际答案)或保留这个问题。
  • @jdweng Span&lt;T&gt; 的关键点之一是它不再需要使用unsafe 或C++ 来利用这种100% 托管/"安全”的内存使用

标签: c# struct system.memory


【解决方案1】:

哎呀。看起来MemoryMarshal.Cast 曾经是NonPortableCast 扩展方法(来自:this commit),在这种情况下 - 是的,这是在跨度布局之间进行转换的适当方法,最常见(但不完全)像在这种情况下 - 在byte 和一些struct 之间。

【讨论】:

    猜你喜欢
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 2016-11-08
    • 2013-02-11
    • 2014-12-28
    相关资源
    最近更新 更多