[英]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.