简体   繁体   中英

How can I pin an array of byte?

I want to pin an array of bytes which is 10 megabytes long so that managed and unmanaged code can work on it.

My scenario is that I have an unmanaged driver which reads some data from the device and writes it to the big array and the managed application just reads that data.

Something like this:

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

I want to pin dataArray so that GC does not move it.

What happens actually when I just run the application, I get a DataAbortApplication, and after reading on the internet I found out that I should pin the dataArray to avoid this error.

How/what should I do?

There are 2 ways to do this. The first is to use the fixed statement:

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

However, it sounds like you want the array pinned for a longer period of time. You can use GCHandle s to accomplish this:

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();
}

Here is a class that can be used to pin a byte array until is disposed. However it sounds like a memory mapped file would be more appropriate in your scenario.

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;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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