2011-11-17 5 views
1

2つの独立したC++ DLLから返されたIntPtrを使用するシステムで作業しています。アンマネージメモリは、各DLLに表示されるOBJECT_FREEメソッドを呼び出すことで解放されます。IntPtrを割り当てたDLLを調べる

残念ながら、コードの中には、もともとメモリを割り当てたDLLのトラックが失われています。 Win7に移行して以来、これはアクセス違反となっています(何らかの理由でWinXP上で動作しなくなったため)。

中期的には、これを適切に処理するためにすべてのIntPtrをラップアップする必要がありますが、短期的には、どのDLLが元々メモリを割り当てたかを判断する方法はありますか?

答えて

2

いいえ - 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を参照してください。

+0

問題は、2つのアンマネージライブラリに2つの 'OBJECT_FREE'メソッドがあることです。そこで、それぞれが正しいフリーメソッドを呼び出す2つの 'MySafeHandle'実装が必要になります。 –

+0

@DarinDimitrovはい、これがアイデアです。私はこれをもっと明確にしようと少し答えを書き直しました。 – Justin

+0

SafeHandleのアプローチは間違いなく私の中期的な解決策です。しかし、これが何百もの呼び出しに影響するという事実のために、私は速い勝利を望んでいました。明らかに、IntPtr自体はどこから来たのか分からず、短期間のハックとして使うことができるWindows API呼び出しかもしれないと思っていました。 – Modan

1

唯一のIntPtrが与えられた場合、このチャンクのメモリを割り当てられたアンマネージライブラリを特定する方法はありません。

関連する問題