【发布时间】:2011-03-24 23:25:10
【问题描述】:
我正在将一些套接字代码从 Linux 移植到 Windows。
在 Linux 中,我可以使用 strerror() 将 errno 代码转换为人类可读的字符串。
MSDN 文档显示了从WSAGetLastError() 返回的每个错误代码的等效字符串,但我没有看到有关如何检索这些字符串的任何信息。 strerror() 也可以在这里工作吗?
如何从 Winsock 检索人类可读的错误字符串?
【问题讨论】:
我正在将一些套接字代码从 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);
【讨论】:
&s 参数必须在此处转换为 LPTSTR,因为此函数在此处使用 hack,此参数将指向字符串的指针作为字符串返回。
LPWSTR的演员表,否则编译器会失败
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
【讨论】: