2012-08-15 61 views
13

我已經在網上搜索了很多,但沒有找到一個好的解釋。我可以使用SafeHandle而不是IntPtr嗎?

我的問題很簡單。

我有一個DLL,它有一個名爲Initialize的函數,其中一個參數是一個指針,它將接收一個隨後調用使用的句柄。另一個參數是一個字符串,我將列出它的完整性。我使用的簽名是(在其簡單的形式):

[DllImport(MyDll)] 
static extern bool Initialize([In] string name, out IntPtr handle); 

在DLL本身的簽名寫爲:Initialize(LPTSTR name, HANDLE handle)與評論「HANDLE:指向將接收手柄的位置」。

和隨後的電話是在

[DllImport(MyDll)] 
static extern bool DoSomething(IntPtr handle, uint randomParameter); 

我一直在閱讀有關SafeHandle,我想知道如果我可以用它來substite我IntPtr的手柄形式。如果可以,我該怎麼做?擴展抽象SafeHandle類不是問題,但是我可以直接將IntPtr替換爲SafeHandle(並使用默認編組)嗎?還是需要額外執行一些操作?

+0

什麼好處呢'SafeHandle'給你,只是存儲'IntPtr'纔不是? – 2012-08-15 16:25:16

+4

@ScottChamberlain - 'SafeHandle'是'IDisposable',並確保釋放句柄引用的資源。'IntPtr'只是一個可以傳遞的指針大小的值 - 它沒有處理語義。 – LBushkin 2012-08-15 16:31:01

+0

假設你可以爲內存付費,除非你可以使用'Marshal.FreeBSTR','Marshal.FreeCoTaskMem'或Marshal.FreeHGlobal'去取指針內存,否則我認爲你不能安全地 - 從C#分配內存。使用'IntPtr',C#不會自動釋放任何內存。 – Pooven 2012-08-15 16:44:25

回答

10

您可以找到有關SafeHandleIntPtr之間的區別就在這裏一個更完整的答案:IntPtr, SafeHandle and HandleRef - Explained

然而,總結,IntPtr應該用在參數實際上是一個機器尺寸指針 - SafeHandle應用於參數實際上是Win32句柄的地方。這些類型通常不可互換; IntPtr的大小在不同的體系結構上會有所不同(x86上爲32位,x64和amd64上爲64位)。注意:在蓋子下,我認爲SafeHandle也使用IntPtr)。

此外,與IntPtr,SafeHandle不同,實際上在垃圾收集類型時執行資源處置。這可確保在程序運行時系統資源不會泄露(儘管您應儘早使用SafeHandle實例Dispose())。請注意,SafeHandle實際上是抽象的,因爲有許多不同種類的手柄需要不同的方法進行適當的處​​理和處理。

在您的具體情況下,您需要查看您正在調用的DLL的文檔。如果它是一個Win32 DLL,可能已經有一個SafeHandle類型。如果它是第三方DLL,那麼您可以推出自己的SafeHandle實施 - 假設除Initialize()之外還有一些版本Release()(或同等版本)。

約IntPtr的一些其他有趣的花絮VS的SafeHandle,可以發現:

Use SafeHandle to encapsulate native resources

SafeHandle Class Reference

SafeHandles and Critical Finalization

+0

當然'IntPtr'是64位而不是65?我做了編輯 - 請回復並解釋更多(我準備好這是我的「每天都會學到新的東西」) – sblom 2012-08-15 16:49:32

+0

那麼,正如我所說創建自己的SafeHandle實現沒什麼大不了的,有很多例子我想知道的是,如果我可以使用SafeHandle和IntPtr可互換,那麼我可以這樣做:'static static extern bool Initialize([In] string name,out SafeHandle)'' [In]字符串名稱,out IntPtr)'? – Davio 2012-08-15 17:21:45

+0

@sblom:Nope,這只是我的一個錯字,感謝您的支持 – LBushkin 2012-08-15 17:56:59

相關問題