LinuxからWindowsにいくつかのソケットコードを移植しています。
Linuxでは、strerror()
を使用して、errnoコードを人間が読める文字列に変換できます。
MSDNのドキュメントには、WSAGetLastError()
から返された各エラーコードに相当する文字列が示されていますが、これらの文字列を取得する方法については何もわかりません。 strerror()
はここでも機能しますか?
Winsockから人間が読めるエラー文字列を取得するにはどうすればよいですか?
WSAGetLastError
のドキュメントにあるように、 FormatMessage
を使用してエラーメッセージのテキストバージョンを取得できます。
dwFlags
パラメータにFORMAT_MESSAGE_FROM_SYSTEM
を設定し、エラーコードをdwMessage
パラメータとして渡す必要があります。
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);
Mxclの回答の少し単純なバージョンで、malloc/freeの必要性とそこに内在するリスクを排除し、メッセージテキストが利用できない場合を処理します(Microsoftはそのとき何が起こるかを文書化していないため)。
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