【问题标题】:How to assign (byte* + offset) to byte[]?如何将 (byte* + offset) 分配给 byte[]?
【发布时间】:2015-10-02 15:28:26
【问题描述】:

我有一个结构:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct FieldIndex {
   public fixed byte Meta[16];
}

第一个字节是TypeCode。剩下的 15 个字节是一个 UTF8 编码的字符串。

我正在使用以下内容来填充nameBuf 字节数组:

  private static string GetMetaName (FieldIndex meta) {
     var idx = 0;
     var bytesOut = 1;
     var nameBuf = new byte[Indexer.MAXFIELDNAMELENGTH];   // 15

     while (bytesOut < Indexer.MAXFIELDLENGTH) {           // 16
        nameBuf[idx] = *(byte*)((byte*)&meta + bytesOut);

        ++bytesOut;
        ++idx;
     }

     //var src = (byte*)&field.meta + 1;
     //fixed (byte* b = nameBuf) {
     //   *((byte*)b) = (byte)src;
     //}

     return BinaryConverter.ToString(nameBuf, 0, Indexer.MAXFIELDNAMELENGTH, Indexer.DefaultEncoding);
  }

在上面注释的代码中,我试图在没有while 迭代的情况下完成相同的任务,但它不起作用(没有编译错误,只是插值错误)。我可以在没有while-loop 的情况下分配nameBuf 吗?

更新
我也更喜欢使用(byte*) 而不是Marshal.Copy

【问题讨论】:

    标签: c# buffer bytearray unsafe-pointers


    【解决方案1】:

    您可以尝试在unsafe 上下文中使用Marshal.Copy 静态方法:

    unsafe
    {
        Marshal.Copy(new IntPtr(meta), nameBuf, 1, nameBuf.Length);
    }
    

    【讨论】:

    • Marshal.Copy 只是隐藏while 循环(本质上)?
    • 别在意这个问题。我查看了实现,它调用了一个extern 方法(可能是C),这很可能类似于Mono 在这里所做的:github.com/mono/mono/blob/… 我正在寻找一种在没有Marshalling 的情况下使用byte* + offset 的方法。我会更新我的问题,看看我能不能明白。
    • Marshal.Copy 实际上导致异常:超出范围。当您编写它时,实现给出了一个编译错误,所以我对其进行了一些修改:Marshal.Copy(new IntPtr((byte*)&amp;meta), nameBuf, 1, nameBuf.Length)
    【解决方案2】:

    如果您可以通过这种方式轻松地做到这一点,那么采用这种硬不安全的方式就没有多大意义了:

    [StructLayout(LayoutKind.Sequential)]
    struct FieldIndex {
       public byte Typecode;
       [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)]
       private byte[] Utf8string;
       public string GetString() {
          return Encoding.UTF8.GetString(Utf8string, 0, 15);
       }
    }
    

    没有while循环,任务完成。该指针仍然存在并且同样有效,您只是不再看到它。如果您担心过于频繁地调用 GetString() 方法,那么只需声明另一个公共类并将其保留在内部。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多