2013-10-06 26 views
1

我試圖找出一種方法讓我的VirtualAlloc的pinvoke簽名返回一個PageAlignedBuffer。我遇到的問題是我不能有一個默認構造函數,因爲VirtualFree方法需要知道緩衝區大小,所以我必須在構造函數中提供它。出於這個原因,我採取了下面的方法,並從構造函數中調用VirtualAlloc。如何爲VirtualAlloc製作PInvoke SafeHandle

有沒有人看到一種解決方法,所以我可以從pinvoke調用返回一個PageAlignedBuffer?如果不是這是一個好的解決方案,你是否看到它有任何安全或內存泄漏問題?謝謝。

[SecurityCritical] 
public sealed class PageAlignedBuffer : SafeBuffer 
{ 
    private readonly UIntPtr _bufferSize = UIntPtr.Zero; 
    public PageAlignedBuffer(long bufferSize) : base(true) 
    { 
     _bufferSize = checked ((UIntPtr) bufferSize); 
     this.handle = WinAPI.VirtualAlloc(IntPtr.Zero, _bufferSize, AllocationType.RESERVE | AllocationType.COMMIT, MemoryProtection.READWRITE); 
    } 
    [SecurityCritical] 
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
    protected override bool ReleaseHandle() 
    { 
     return WinAPI.VirtualFree(this.handle, _bufferSize, FreeType.Release); 
    } 
} 

回答

1

我想你應該通過零dwSize當你ReleaseHandle調用VirtualFreeas mentioned on MSDN

如果dwFreeType參數MEM_RELEASE,這個參數必須爲0 (零)。該函數將在初始分配調用中保留的整個區域釋放到VirtualAlloc。

因此,你並不需要保存_bufferSize,但你仍然需要從SafeBuffer派生類,因爲SafeBuffer是需要您實現ReleaseHandle在派生類中,對付一個抽象類特定的資源類型。這樣,你的PageAlignedBuffer是一個託管類,你不能讓VirtualAlloc API返回它的一個實例或者將一個非託管指針指向它。所以,其餘的代碼對我來說看起來不錯。