Dav*_*vio 16 c# pinvoke handle marshalling
我在网上广泛搜索但没有找到一个好的解释.
我的问题非常简单.
我有一个DLL,它有一个名为Initialize的函数,其中一个参数是一个指针,它将接收一个句柄,用于后续调用.另一个参数是一个字符串,我将列出完整性.我正在使用的签名是(简单形式):
[DllImport(MyDll)]
static extern bool Initialize([In] string name, out IntPtr handle);
Run Code Online (Sandbox Code Playgroud)
DLL本身的签名写为:Initialize(LPTSTR name, HANDLE handle)
注释"HANDLE:指向将接收句柄的位置".
随后的电话采取的形式
[DllImport(MyDll)]
static extern bool DoSomething(IntPtr handle, uint randomParameter);
Run Code Online (Sandbox Code Playgroud)
我一直在阅读SafeHandle
,我想知道我是否可以用它来替代我的IntPtr句柄.如果可以的话,我该怎么做?扩展抽象的SafeHandle类不是问题,但我可以直接用IntPtr替换SafeHandle(并使用默认编组)或者我是否需要做一些额外的事情?
LBu*_*kin 10
你可以找到一个更完整的答案,关于SafeHandle
和IntPtr
这里之间的差异: IntPtr,SafeHandle和HandleRef - 解释
但是,总而言之,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的一些其他有趣的花絮可以在以下位置找到: