簡體   English   中英

如何固定一個字節數組?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM