我搜索了互联网,但没有找到很好的解释。

我的问题很简单。

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

最佳答案

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

但是,总而言之,应该在参数实际上是机器大小的指针的地方使用IntPtr-在参数实际上是Win32句柄的地方应该使用SafeHandle。这些类型通常不可互换。 IntPtr的大小在不同的体系结构上会有所不同(x86上为32位,x64和amd64上为64位)。注意:在幕后,我相信SafeHandle也使用IntPtr)。

另外,与IntPtr不同,SafeHandle实际上在垃圾回收类型时执行资源处置。这样可以确保在程序运行时不会泄漏系统资源(尽管应尽可能早地将Dispose()实例的SafeHandle)。注意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

关于c# - 我可以使用SafeHandle代替IntPtr吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11973109/

10-11 19:08