【发布时间】:2016-08-26 14:15:28
【问题描述】:
我正在从 C++ 代码调用 Windows API,并且我有一个辅助方法来执行 FormatMessage 的工作并引发异常以进行错误处理。函数的签名是
void throw_system_error(const std::string& msg_prefix, DWORD messageid)
我注意到了一些奇怪的事情。此代码无法正常工作:
handle = ...;
if (handle == NULL) {
throw_system_error("something bad happened", GetLastError());
}
传递给throw_system_error 的错误代码始终为零。
在哪里可以正常工作:
handle = ...;
if (handle == NULL) {
DWORD error = GetLastError();
throw_system_error("something bad happened", error);
}
更多调查表明这个版本有同样的问题:
handle = ...;
if (handle == NULL) {
std::string msg("something bad happened");
DWORD error = GetLastError();
throw_system_error(msg, error);
}
就像std::string的构造函数正在重置错误代码一样寻找全世界。
我的猜测是std::string 在内部分配内存,这会导致一些系统调用,然后将最后一个错误设置为零。
有人知道这里到底发生了什么吗?
Visual C++ 2015,64 位。
【问题讨论】:
-
您的代码已损坏。就那么简单。在调用任何其他 API 函数之前调用
GetLastError。显然,分配内存的调用可能会调用SetLastError。我很确定以前在这里有人问过这个问题。 -
代码已损坏,但我要求的是根本原因,而不是修复。为了增加谜团,我已经测试了 HeapAlloc 并且它不会修改 last-error。但是 malloc 将其设置为零。作为 GetLastError 要求的文档,msdn 上没有记录。那么...我应该接受哪个答案?
-
malloc不在 MSDN Win32 文档的范围内。它可以为所欲为。 -
您可能需要考虑抛出一个仅由错误代码构造的std::system_error。如果您需要在任意子系统边界添加字符串前缀,您可以在接口实现中的适当
catch子句中实现代码来执行此操作。
标签: c++ winapi error-handling