2010-08-03 10 views
21

Przenoszę niektóre kody gniazd z Linux na Windows.Jak pobrać ciąg znaków błędu z WSAGetLastError()?

W systemie Linux można użyć strerror() do konwersji kodu errno na ciąg czytelny dla człowieka.

Dokumentacja MSDN pokazuje równoważne ciągi dla każdego kodu błędu zwrócony z WSAGetLastError(), ale nie widzę nic o tym, jak pobrać te ciągi. Czy tutaj też będzie działało strerror()?

Jak mogę pobrać odczytywane przez ludzi ciągi znaków błędu z Winsock?

Odpowiedz

14

Dokumentacja dla WSAGetLastError mówi, że można użyć FormatMessage, aby uzyskać wersję tekstową komunikatu o błędzie.

Należy ustawić FORMAT_MESSAGE_FROM_SYSTEM w parametrze dwFlags i przekazać kod błędu jako parametr dwMessage.

+1

Dzięki - właśnie to odkryłem. Muszę pamiętać, aby spojrzeć na MSDN online (w przeciwieństwie do kopii off-line zainstalowanej na moim laptopie!). –

27
wchar_t *s = NULL; 
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
       NULL, WSAGetLastError(), 
       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
       (LPWSTR)&s, 0, NULL); 
fprintf(stderr, "%S\n", s); 
LocalFree(s); 
+2

Argument '& s' musi zostać przeniesiony do LPTSTR tutaj, ponieważ ta funkcja używa hackowania z tym parametrem, zwracając wskaźnik do łańcucha jako ciąg znaków. –

+1

Tylko jeśli zmienisz również FormatMessageW na FormatMessage. W przeciwnym razie może być konieczne przesłanie do LPWSTR, w zależności od ustawień w twoim projekcie Visual Studio. –

+0

Edytowałem odpowiedź, aby dołączyć rzutowanie do 'LPWSTR', w przeciwnym razie kompilator nie powiedzie się – SailAvid

2

Nieco prostsza wersja odpowiedzi mxcl, co eliminuje potrzebę malloc/free i ryzyka ukryte w nim, i który obsługuje przypadek, w którym nie tekst wiadomości jest dostępne (ponieważ Microsoft nie dokumentuje, co dzieje się potem):

int 
    err; 

char 
    msgbuf [256]; // for a message up to 255 bytes. 


msgbuf [0] = '\0'; // Microsoft doesn't guarantee this on man page. 

err = WSAGetLastError(); 

FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, // flags 
       NULL,    // lpsource 
       err,     // message id 
       MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // languageid 
       msgbuf,    // output buffer 
       sizeof (msgbuf),  // size of msgbuf, bytes 
       NULL);    // va_list of arguments 

if (! *msgbuf) 
    sprintf (msgbuf, "%d", err); // provide error # if no string available 
Powiązane problemy