【问题标题】:Detemine which DLL allocated IntPtr确定哪个 DLL 分配了 IntPtr
【发布时间】:2011-11-17 13:38:15
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# memory-management interop intptr


    【解决方案1】:

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

    如果您需要释放与 IntPtr 关联的内存,那么我建议您为两个单独的 C++ DLL 中的每一个都使用 implement a safe handle,并修改您的 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 相关的资源的正确方法。

    请参阅安全手柄上的this MSDN blog article 了解更多信息。

    【讨论】:

    • 问题是他在2个非托管库中有两个OBJECT_FREE方法。所以他还需要 2 个MySafeHandle 实现,每个实现都调用正确的免费方法。
    • @DarinDimitrov 是的,这就是我的想法 - 我已经稍微改写了我的答案,试图让这个更清楚。
    • SafeHandle 方法绝对是我的中期解决方案。然而,由于这会影响数百个电话,我希望能快速获胜。显然 IntPtr 本身不知道它来自哪里,我希望这可能是一个我可以使用的 Windows API 调用或其他一些机制作为短期破解。
    【解决方案2】:

    仅给定一个IntPtr,无法确定哪个非托管库分配了这块内存。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-03
      • 2012-02-09
      • 2018-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多