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