如何固定一个字节数组?

Shr*_*Shr 16 .net c# arrays

我想固定一个10兆字节的字节数组,以便托管和非托管代码可以使用它.

我的方案是我有一个非托管驱动程序,它从设备读取一些数据并将其写入大数组,托管应用程序只读取该数据.

像这样的东西:

byte[] dataArray = new byte[10*1024*1024];
Run Code Online (Sandbox Code Playgroud)

我想固定dataArray,以便GC不移动它.

实际上,当我运行应用程序时,我得到一个DataAbortApplication,并在互联网上阅读后发现我应该固定dataArray以避免此错误.

我该怎么做?

por*_*ges 25

有两种方法可以做到这一点.首先是使用fixed声明:

unsafe void UsingFixed()
{
    var dataArray = new byte[10*1024*1024];
    fixed (byte* array = dataArray)
    {
        // array is pinned until the end of the 'fixed' block
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,听起来你想要将阵列固定更长的时间.您可以使用GCHandle来完成此任务:

void UsingGCHandles()
{
    var dataArray = new byte[10*1024*1024];
    var handle = GCHandle.Alloc(dataArray, GCHandleType.Pinned);

    // retrieve a raw pointer to pass to the native code:
    IntPtr ptr = handle.ToIntPtr();

    // later, possibly in some other method:
    handle.Free();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果托管代码和非托管代码在同一进程中,这将起作用.要共享跨进程,您需要使用内存映射文件. (5认同)
  • 使用“handle.AddrOfPinnedObject()”而不是“handle.ToIntPtr()” (2认同)