Как получить последнюю ошибку (WSAGetLastError)? - PullRequest
8 голосов
/ 19 апреля 2009

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

Ответы [ 4 ]

20 голосов
/ 19 апреля 2009
[DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern Int32 WSAGetLastError();

Также на pinvoke.net сказано:

Вы никогда не должны вызывать GetLastError. Вместо этого вызовите Marshal.GetLastWin32Error!

System.Runtime.InteropServices.Marshal.GetLastWin32Error ()

7 голосов
/ 19 апреля 2009

WSAGetLastError - это просто оболочка для функции Win32 GetLastError.

Если вы работаете с P / Invoke, вы можете использовать параметр SetLastError для атрибута DllImport. Он сообщает .NET, что импортированная функция будет вызывать SetLastError(), и что значение должно быть собрано.

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

Если вы не работаете с P / Invoke, вам не повезло: нет гарантии, что значение последней ошибки будет сохраняться достаточно долго, чтобы вернуться через несколько уровней кода .NET. Фактически, я сделаю ссылку на Адама Натана: никогда не определяйте подпись PInvoke для GetLastError .

0 голосов
/ 17 июля 2009

Вот как я видел в Интернете, чтобы поместить 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 определяется следующим образом:

0 голосов
/ 19 апреля 2009

Не имеет особого смысла вызывать эту функцию из управляемого кода. Это имеет смысл в неуправляемом коде, потому что вы знаете точную последнюю вызванную функцию Win32, поэтому вы знаете, какая функция должна была установить последнюю ошибку. В управляемом коде вы не знаете, какие функции были вызваны.

Возможно, вы могли бы использовать P / Invoke для вызова функции; это просто не поможет тебе. Что вы пытаетесь достичь?

...