在 DLL 中捕获未处理的异常
Catching unhanded exceptions in a DLL
我正在 .dll 项目中使用 Visual Studio Express 2013 编写 C++ 套接字代码。我正处于此 sendto
函数出错的地步:
/* Send data back */
if (sendto(sd, (const char *)sendBuffer,(int)sizeof(sendBuffer), 0,
(struct sockaddr *)&client, sizeof(client)) ==
SOCKET_ERROR)
{
err = WSAGetLastError();
closesocket(sd);
WSACleanup();
throw std::runtime_error("Error sending datagram.");
}
我知道我们可以使用 WSAGetLastError()
获得错误代码,但如果我将其初始化为变量,我似乎只会得到垃圾数字。如何提取 sendto
错误?我编写了单元测试来测试这个 dll,但我不确定是否有办法打印出错误。
编辑:所以在将条件更改为 == not != 后,它不再在 sendto
处失败,但现在在
处失败
bytes_received = recvfrom(sd, readBuffer, NTP_PACKET_MAX, 0, (struct sockaddr *)&client, &len);
if (bytes_received == SOCKET_ERROR)
{
err = WSAGetLastError();
closesocket(sd);
WSACleanup();
throw std::runtime_error("Could not receive datagram.");
}
和原来的问题一样,我不确定如何得到正确的错误。调试 recvfrom
函数时,我将鼠标悬停在 err
上,它表示它保存的值为 114351196。据我所知,这不是有效的 Windows 套接字错误代码。
你的代码中有几个严重的错误
/* Send data back */
if (sendto(sd, (const char *)sendBuffer,(int)sizeof(sendBuffer), 0,
(struct sockaddr *)&client, sizeof(client)) !=
SOCKET_ERROR) // SHOULD BE == (1)
{
throw std::runtime_error("Error sending datagram.");
// UNREACHABLE CODE (2)
closesocket(sd);
WSACleanup();
}
错误1:发送成功时进入了您的错误块。这可能意味着您的错误未初始化(如果不是,它将是来自其他地方的最后一个错误值)。根据 WSAGetLastError
的 MSDN 文档,应在 WinSocket 操作失败后立即调用该函数,并且仅在这些情况下。
如果您在(您正在执行的)操作成功后调用它,则无法保证您将收到什么值。如果可能是此线程上另一个 WinSocket 操作的最后一个错误,则它可能是 0,也可能是其他值。文档没有说明如果在没有操作失败时检索到错误会发生什么,因此您可以将此视为未定义的行为。
错误 2:抛出异常后,函数将立即退出。您不会调用 closesocket
或 WSACleanup
更新:
我猜您是在为 err
赋值之前在调试器中检查它的值。你应该按照以下方式做一些事情:
bytes_received = recvfrom(sd, readBuffer, NTP_PACKET_MAX, 0, (struct sockaddr *)&client, &len);
if (bytes_received == SOCKET_ERROR)
{
int err = WSAGetLastError();
// In debugger you must be here before err is set
closesocket(sd);
WSACleanup();
std::string what{"Could not receive datagram."};
what+= std::to_string(err);
throw std::runtime_error(what.c_str());
}
我正在 .dll 项目中使用 Visual Studio Express 2013 编写 C++ 套接字代码。我正处于此 sendto
函数出错的地步:
/* Send data back */
if (sendto(sd, (const char *)sendBuffer,(int)sizeof(sendBuffer), 0,
(struct sockaddr *)&client, sizeof(client)) ==
SOCKET_ERROR)
{
err = WSAGetLastError();
closesocket(sd);
WSACleanup();
throw std::runtime_error("Error sending datagram.");
}
我知道我们可以使用 WSAGetLastError()
获得错误代码,但如果我将其初始化为变量,我似乎只会得到垃圾数字。如何提取 sendto
错误?我编写了单元测试来测试这个 dll,但我不确定是否有办法打印出错误。
编辑:所以在将条件更改为 == not != 后,它不再在 sendto
处失败,但现在在
bytes_received = recvfrom(sd, readBuffer, NTP_PACKET_MAX, 0, (struct sockaddr *)&client, &len);
if (bytes_received == SOCKET_ERROR)
{
err = WSAGetLastError();
closesocket(sd);
WSACleanup();
throw std::runtime_error("Could not receive datagram.");
}
和原来的问题一样,我不确定如何得到正确的错误。调试 recvfrom
函数时,我将鼠标悬停在 err
上,它表示它保存的值为 114351196。据我所知,这不是有效的 Windows 套接字错误代码。
你的代码中有几个严重的错误
/* Send data back */
if (sendto(sd, (const char *)sendBuffer,(int)sizeof(sendBuffer), 0,
(struct sockaddr *)&client, sizeof(client)) !=
SOCKET_ERROR) // SHOULD BE == (1)
{
throw std::runtime_error("Error sending datagram.");
// UNREACHABLE CODE (2)
closesocket(sd);
WSACleanup();
}
错误1:发送成功时进入了您的错误块。这可能意味着您的错误未初始化(如果不是,它将是来自其他地方的最后一个错误值)。根据 WSAGetLastError
的 MSDN 文档,应在 WinSocket 操作失败后立即调用该函数,并且仅在这些情况下。
如果您在(您正在执行的)操作成功后调用它,则无法保证您将收到什么值。如果可能是此线程上另一个 WinSocket 操作的最后一个错误,则它可能是 0,也可能是其他值。文档没有说明如果在没有操作失败时检索到错误会发生什么,因此您可以将此视为未定义的行为。
错误 2:抛出异常后,函数将立即退出。您不会调用 closesocket
或 WSACleanup
更新:
我猜您是在为 err
赋值之前在调试器中检查它的值。你应该按照以下方式做一些事情:
bytes_received = recvfrom(sd, readBuffer, NTP_PACKET_MAX, 0, (struct sockaddr *)&client, &len);
if (bytes_received == SOCKET_ERROR)
{
int err = WSAGetLastError();
// In debugger you must be here before err is set
closesocket(sd);
WSACleanup();
std::string what{"Could not receive datagram."};
what+= std::to_string(err);
throw std::runtime_error(what.c_str());
}