如何为VirtualAlloc制作PInvoke SafeHandle

时间:2013-10-06 03:03:43

标签: c# .net pinvoke

我正试图想办法让VirtualAlloc的pinvoke签名返回PageAlignedBuffer。我遇到的问题是我不能拥有默认构造函数,因为VirtualFree方法需要知道缓冲区大小,所以我必须在构造函数中提供它。出于这个原因,我采用了下面的方法,只需从构造函数中调用VirtualAlloc即可。

有没有人看到这个方法,所以我可以从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 个答案:

答案 0 :(得分:1)

我认为当您在dwSizeas mentioned on MSDN中致电VirtualFree时,您应该为ReleaseHandle传递零:

  

如果dwFreeType参数是MEM_RELEASE,则此参数必须为0   (零)。该函数释放了在中保留的整个区域   初始分配调用VirtualAlloc。

因此,您不需要存储_bufferSize,但仍需要从SafeBuffer派生一个类,因为SafeBuffer是一个抽象类,需要您实现派生类中的ReleaseHandle,用于处理特定的资源类型。这样,您的PageAlignedBuffer是托管类,您无法让VirtualAlloc API返回它的实例或者向其投出非托管指针。所以,你的其余代码对我来说很好。