【发布时间】:2010-10-20 09:53:32
【问题描述】:
如何从 WinAPI 调用 WSAGetLastError() 以获取有效文本错误?
【问题讨论】:
标签: c# .net winapi error-handling pinvoke
如何从 WinAPI 调用 WSAGetLastError() 以获取有效文本错误?
【问题讨论】:
标签: c# .net winapi error-handling pinvoke
[DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern Int32 WSAGetLastError();
另外,pinvoke.net 上说:
您永远不应该 PInvoke 到 GetLastError。改为调用 Marshal.GetLastWin32Error!
【讨论】:
WSAGetLastError 只是 Win32 GetLastError 函数的包装器。
如果您使用 P/Invoke 执行操作,则可以将 SetLastError 参数用于 DllImport 属性。它告诉 .NET 导入的函数将调用 SetLastError(),并且应该收集该值。
如果导入的函数失败,您可以使用Marshal.GetLastWin32Error() 获取最后一个错误。或者,您可以只使用throw new Win32Exception(),它会自动使用此值。
如果您不使用 P/Invoke 执行操作,那么您就很不走运:无法保证最后一个错误值将保留足够长的时间以使其通过多层 .NET 代码返回。事实上,我将链接到 Adam Nathan:never define a PInvoke signature for GetLastError。
【讨论】:
从托管代码调用该函数没有多大意义。这在非托管代码中是有意义的,因为您知道调用的确切最后一个 Win32 函数,因此您知道必须设置最后一个错误的函数。在托管代码中,您不知道调用了哪些函数。
您可能可以使用 P/Invoke 来调用该函数;这对你没有任何好处。你想完成什么?
【讨论】:
这就是我在网上看到的如何将GetLastError放入C#异常机制中以及如何将其重新取出...
try
{
// some p/invoke call that is going to fail with a windows error ...
mHndActivatedDevice = MyNameSpace.Interop.Device.Device.ActivateDevice(
"Drivers\\BuiltIn\\SomeDriverName", IntPtr.Zero, 0, IntPtr.Zero);
}
catch(System.ComponentModel.Win32Exception exc) // as suggested by John Saunders
{
// you can get the last error like this:
int lastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
Console.WriteLine("error:" + lastError.ToString());
// but it is also inside the exception, you can get it like this
Console.WriteLine(exc.NativeErrorCode.ToString());
Console.WriteLine(exc.ToString());
}
ActivateDevice 的定义如下:
【讨论】: