Как получить последнюю ошибку (WSAGetLastError)?

Как позвонить WSAGetLastError() от WinAPI, поэтому я получаю допустимую текстовую ошибку?

4 ответов


[DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern Int32 WSAGetLastError();

кроме того, on pinvoke.net сказано:

вы никогда не должны PInvoke для GetLastError. Позвони Маршалу.Вместо GetLastWin32Error!


WSAGetLastError - Это просто оболочка для Win32 до . Он сообщает .NET, что импортированная функция вызовет SetLastError(), и что значение должно быть собрано.

если импортированная функция терпит неудачу, вы можете получить последнюю ошибку с Marshal.GetLastWin32Error(). Кроме того, вы можете просто throw new Win32Exception(), который использует это значение автоматически.

если вы не делаете вещи с P / Invoke, вам не повезло: нет никакой гарантии, что последнее значение ошибки будет сохранено достаточно долго, чтобы вернуться через несколько слоев кода .NET. На самом деле, я свяжусь с Адамом Натаном:никогда не определяйте подпись PInvoke для 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 определяется таким образом: