繁体   English   中英

如何固定一个字节数组?

[英]How can I pin an array of byte?

我想固定一个 10 兆字节长的字节数组,以便托管和非托管代码可以处理它。

我的场景是我有一个非托管驱动程序,它从设备读取一些数据并将其写入大阵列,托管应用程序只读取该数据。

像这样的东西:

byte[] dataArray = new byte[10*1024*1024];

我想固定 dataArray 以便 GC 不会移动它。

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

我该怎么做/我该怎么做?

有两种方法可以做到这一点。 第一种是使用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
    }
}

但是,听起来您希望阵列固定更长时间。 您可以使用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();
}

这是一个可用于固定字节数组直到被处理的类。 但是,听起来像内存映射文件在您的场景中更合适。

public class PinnedBuffer : IDisposable
{
    public GCHandle Handle { get; }
    public byte[] Data { get; private set; }

    public IntPtr Ptr
    {
        get
        {
            return Handle.AddrOfPinnedObject();
        }
    } 

    public PinnedBuffer(byte[] bytes)
    {
        Data = bytes;
        Handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            Handle.Free();
            Data = null;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM