How can I pin an array of byte?

前端 未结 2 985
谎友^
谎友^ 2020-12-30 01:58

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 re

相关标签:
2条回答
  • 2020-12-30 02:37

    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;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-30 02:57

    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 GCHandles 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();
    }
    
    0 讨论(0)
提交回复
热议问题