1

我试图找出一种方法让我的 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);
    }
}
4

1 回答 1

1

我认为你应该dwSize在打电话时VirtualFree传递零ReleaseHandle如 MSDN 上所述

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

因此,您不需要 store _bufferSize,但您仍然需要从 派生一个类SafeBuffer,因为SafeBuffer它是一个抽象类,需要您ReleaseHandle在派生类中实现,以处理特定的资源类型。这样,您PageAlignedBuffer是一个托管类,您不能让VirtualAllocAPI 返回它的实例或将非托管指针投射到它。所以,你的其余代码对我来说看起来不错。

于 2013-10-06T05:06:41.547 回答