我可以使用SafeHandle而不是IntPtr吗?

时间:2012-08-15 16:22:51

标签: c# pinvoke marshalling handle

我在网上广泛搜索但没有找到好的解释。

我的问题非常简单。

我有一个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,我想知道我是否可以用它来替代我的IntPtr句柄。如果可以的话,我该怎么做?扩展抽象的SafeHandle类不是问题,但是我可以直接用IntPtr替换SafeHandle(并使用默认编组)或者我是否需要做额外的事情?

1 个答案:

答案 0 :(得分:10)

您可以在此处找到有关SafeHandleIntPtr之间差异的更完整答案:IntPtr, SafeHandle and HandleRef - Explained

但是,总而言之,IntPtr应该在参数实际上是机器大小指针的情况下使用 - SafeHandle应该在参数实际上是Win32句柄的地方使用。这些类型通常不可互换; IntPtr的大小会因不同的体系结构而异(x86为32位,x64为64位,amd64为64位)。注意:在我认为SafeHandle使用IntPtr的情况下,我知道。

此外,与IntPtr不同,SafeHandle实际上在垃圾收集类型时执行资源处理。这可以确保在程序运行时系统资源不会泄露(尽管在可能的情况下,您应尽早Dispose() SafeHandle个实例。请注意SafeHandle实际上是抽象的,因为有许多不同类型的句柄需要不同的方法来进行适当的处​​理和处理。

在您的特定情况下,您需要查看您正在调用的DLL的文档。如果它是Win32 DLL,可能已经有一个SafeHandle类型。如果它是第三方DLL,那么您可以推出自己的SafeHandle实现 - 假设除Initialize()之外还有某些版本的Release()(或等效版本)。

关于IntPtr与SafeHandle的一些其他有趣的花絮可在以下网址找到:

Use SafeHandle to encapsulate native resources

SafeHandle Class Reference

SafeHandles and Critical Finalization