我搜索了互联网,但没有找到很好的解释。
我的问题很简单。
我有一个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(并使用默认的编码)还是需要做些额外的事情吗? 最佳答案
您可以在此处找到有关SafeHandle
和IntPtr
之间的区别的更完整答案: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/