2011-11-17 23 views
1

我正在使用IntPtr從兩個單獨的C++ DLL返回的系統上工作。通過調用每個DLL中提供的OBJECT_FREE方法釋放非託管內存。Determine DLL分配IntPtr

不幸的是,一些代碼丟失跟蹤哪個DLL最初分配的內存。這會導致訪問衝突,因爲我們已經轉移到Win7上(出於某種原因,我們在WinXP上使用它)。在中期內,我將不得不包裝每一個IntPtr來正確處理這個問題,但在短期內,有沒有什麼辦法可以確定哪個DLL最初分配內存?

回答

2

否 - 一個IntPtr只是一個簡單的整數(實際上是一個指針)的包裝 - 沒有額外的元數據,並且根據它來自的數字顯然是不可能的。

如果你需要釋放與IntPtr相關的內存那麼我建議你implement a safe handle爲每個兩個獨立的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相關的資源的正確方法。

請參閱this MSDN blog article瞭解更多信息。

+0

問題是他在兩個非託管庫中有兩個'OBJECT_FREE'方法。所以他還需要2個'MySafeHandle'實現,每個實例都調用正確的自由方法。 –

+0

@DarinDimitrov是的,這是這個想法 - 我已經重新回答了我的答案,試圖讓這個更清晰。 – Justin

+0

SafeHandle方法絕對是我的中期解決方案。然而,由於這影響了數百個電話,我希望快速取勝。很明顯,IntPtr本身並不知道它來自哪裏,我希望它可能是一個Windows API調用,我可能會使用它或其他一些機制作爲短期黑客。 – Modan

1

只給出IntPtr無法確定哪個非託管庫分配了這塊內存。