2010-08-03 5 views
21

Sto eseguendo il porting di alcuni codici socket da Linux a Windows.Come recuperare una stringa di errore da WSAGetLastError()?

In Linux, potrei usare strerror() per convertire un codice errno in una stringa leggibile.

La documentazione MSDN mostra stringhe equivalenti per ciascun codice di errore restituito da WSAGetLastError(), ma non vedo nulla su come recuperare tali stringhe. strerror() lavorerà anche qui?

Come posso recuperare stringhe di errore leggibili da Winsock?

risposta

14

Poiché la documentazione per WSAGetLastError indica che è possibile utilizzare FormatMessage per ottenere una versione di testo del messaggio di errore.

È necessario impostare FORMAT_MESSAGE_FROM_SYSTEM nel parametro dwFlags e passare il codice di errore come parametro dwMessage.

+1

Grazie - l'ho appena scoperto. Ho bisogno di ricordare di guardare l'MSDN online (rispetto alla copia offline installata sul mio laptop!). –

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

L'argomento '& s' deve essere convertito in LPTSTR qui perché questa funzione utilizza un hack qui con questo parametro che restituisce un puntatore alla stringa come stringa. –

+1

Solo se si modifica anche FormatMessageW in FormatMessage. In caso contrario, potrebbe essere necessario eseguire il cast su LPWSTR, a seconda delle impostazioni nel progetto Visual Studio. –

+0

Ho modificato la risposta per includere il cast in 'LPWSTR', altrimenti il ​​compilatore fallisce – SailAvid

2

Una versione leggermente più semplice della risposta di MXCL, che elimina la necessità di malloc/libera e dei rischi impliciti in esso, e che gestisce il caso in cui nessun testo del messaggio è disponibile (in quanto Microsoft non documenta cosa succede allora):

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