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