C# 以SafeHandle作为参考参数的P/Invoke
我在非托管Dll中有一个函数,它需要指向句柄的指针,例如:C# 以SafeHandle作为参考参数的P/Invoke,c#,pinvoke,ref,safehandle,C#,Pinvoke,Ref,Safehandle,我在非托管Dll中有一个函数,它需要指向句柄的指针,例如: extern "C" __declspec(dllexport) BOOL __stdcall MySetEvent(HANDLE* handle, int size) { if (!handle) return FALSE; assert(sizeof(*handle) == size); printf("MySetEvent(%p, %d)\n", *handle, size); return Se
extern "C" __declspec(dllexport) BOOL __stdcall MySetEvent(HANDLE* handle,
int size)
{
if (!handle) return FALSE;
assert(sizeof(*handle) == size);
printf("MySetEvent(%p, %d)\n", *handle, size);
return SetEvent(*handle);
}
我如何从C#调用它,而不使用该示例中的危险GetHandle
[DllImport("UnmanagedDll", SetLastError = true)]
static extern int MySetEvent(ref IntPtr handle, int size);
AutoResetEvent ev = new AutoResetEvent(false);
var handle = ev.SafeWaitHandle.DangerousGetHandle();
MySetEvent(ref handle, Marshal.SizeOf(handle));
这不起作用(将引发.ctor的MissingMethodException):
修正C++代码,需要处理参数,而不是处理**。考虑到它没有做任何与AutoReTeEvServ.Stand()不同的事情,调用SETEVER()没有任何可想象的优势。C代码是第三方的,并做了一点。上面的代码只是解释问题的一个示例。“这不起作用”并不能解释任何事情。在我看来,
DangerousGetHandle
正是您所需要的。是的,名字里有“危险”,但那是因为你在做一件危险的事。该函数不是“正常的”,不需要吃指向句柄的指针,而真正需要的函数可能无法从托管代码中安全地调用(因为它希望挂起指针或更改指针)。如果您想“安全地”使用DangerousGetHandle
,请阅读如何使用DangerousAddRef
/Release
或编写一些C++/CLI代码,以便更好地粘合C#和非托管DLL。
[DllImport("UnmanagedDll", SetLastError = true)]
static extern int MySetEvent([In] ref SafeHandle handle, int size);
SafeHandle handle = ev.SafeWaitHandle;
MySetEvent(ref handle, Marshal.SizeOf(IntPtr.Zero));