2010-08-03 8 views
21

Estoy portando código de algunos sockets de Linux a Windows.¿Cómo recupero una cadena de error de WSAGetLastError()?

En Linux, podría usar strerror() para convertir un código errno en una cadena legible para humanos.

La documentación de MSDN muestra cadenas equivalentes para cada código de error devuelto desde WSAGetLastError(), pero no veo nada sobre cómo recuperar esas cadenas. ¿Funcionará aquí también el strerror()?

¿Cómo puedo recuperar cadenas de error legibles por humanos de Winsock?

Respuesta

14

Como la documentación para WSAGetLastError dice que puede usar FormatMessage para obtener una versión de texto del mensaje de error.

Debe establecer FORMAT_MESSAGE_FROM_SYSTEM en el parámetro dwFlags y pasar el código de error como el parámetro dwMessage.

+1

Gracias - Acabo de descubrirlo yo mismo. ¡Necesito recordar mirar el MSDN en línea (frente a la copia fuera de línea instalada en mi computadora portátil!). –

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

El argumento '& s' se debe convertir a LPTSTR aquí porque esta función usa un truco aquí con este parámetro devolviendo un puntero a la cadena como una cadena. –

+1

Solo si también cambia FormatMessageW a FormatMessage. De lo contrario, es posible que deba enviarlo a LPWSTR, según la configuración de su proyecto de Visual Studio. –

+0

Edité la respuesta para incluir el molde en 'LPWSTR'; de lo contrario, el compilador falla – SailAvid

2

Una versión ligeramente más simple de la respuesta de mxcl, que elimina la necesidad de malloc/libre y los riesgos en ella implícita, y que maneja el caso en que ningún texto de mensaje está disponible (ya que Microsoft no documenta lo que sucede a continuación,):

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 
Cuestiones relacionadas