确定哪个DLL分配了IntPtr

本文关键字:分配 IntPtr DLL | 更新日期: 2023-09-27 18:14:53

我正在研究一个使用从两个独立的c++ dll返回的IntPtr的系统。通过调用每个DLL中提供的OBJECT_FREE方法来释放非托管内存。

不幸的是,一些代码失去了最初分配内存的DLL的跟踪。这导致了访问冲突,因为我们已经迁移到Win7(由于某种原因,我们在WinXP上侥幸逃脱了)。

在中期,我将不得不包装每个IntPtr来正确处理这个问题,但在短期内,是否有任何方法来确定哪个DLL最初分配了内存?

确定哪个DLL分配了IntPtr

不- IntPtr只是一个整数(实际上是一个指针)的简单包装-没有额外的元数据,显然不可能仅从数字中判断它来自何处。

如果您需要释放与IntPtr相关的内存,那么我建议您为每个单独的c++ dll实现一个安全句柄,并修改PInvoke调用以使用安全句柄,例如:

internal class FirstDllSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    private MySafeFileHandle()
        : base(true)
    {
    }
    override protected bool ReleaseHandle()
    {        
        return NativeMethods.FirstDll_OBJECT_FREE(handle);
    }
}
internal class NativeMethods
{
    [DllImport("whatever.dll")]
    public static extern void FirstDll_OBJECT_FREE(FirstDllSafeHandle handle);
    [DllImport("whatever.dll")]
    public static extern void FirstDll_GetObject(out FirstDllSafeHandle handle);
    [DllImport("whatever.dll")]
    public static extern void SecondDll_OBJECT_FREE(SecondDllSafeHandle handle);
    [DllImport("whatever.dll")]
    public static extern void SecondDll_GetObject(out SecondDllSafeHandle handle);
}

使用安全句柄代替IntPtr提供了许多其他优点,以及无缝地跟踪释放与IntPtr相关的资源的正确方式。

请参阅MSDN博客关于安全句柄的文章以了解更多信息。

如果只给定一个IntPtr,则无法确定哪个非托管库分配了该内存块。