20

我已经在互联网上进行了广泛搜索,但没有找到很好的解释。

我的问题很简单。

我有一个 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(并使用默认编组)还是需要做一些额外的事情?

4

1 回答 1

16

SafeHandle您可以在此处找到有关和之间区别的更完整答案IntPtrIntPtr、SafeHandle 和 HandleRef - 解释

但是,总而言之,IntPtr应该在参数实际上是机器大小指针的情况下使用-SafeHandle应该在参数实际上是 Win32 句柄的情况下使用。这些类型通常不可互换;的大小IntPtr会因不同的架构而异(x86 上为 32 位,x64 和 amd64 上为 64 位)。注意:在封面下我相信也SafeHandle使用了IntPtr)。

此外,与 不同的是,当一个类型被垃圾回收时IntPtrSafeHandle实际上执行资源的处置。这可确保在您的程序运行时不会泄露系统资源(尽管您应该尽可能早地使用实例)Dispose()SafeHandle请注意,这SafeHandle实际上是抽象的,因为有许多不同类型的句柄需要不同的方法来正确处理和处理。

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

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

使用 SafeHandle 封装原生资源

SafeHandle 类参考

SafeHandles 和关键终结

于 2012-08-15T16:26:51.650 回答