问题描述
我有一个Visual Studio 2008 C ++项目,使用 Win32Exception
类在有一个异常错误的情况下。 Win32Exception
类看起来像这样:
I have a Visual Studio 2008 C++ project that uses a Win32Exception
class in cases where there is an exceptional error. The Win32Exception
class looks like this:
/// defines an exception based on Win32 error codes. The what() function will
/// return a formatted string returned from FormatMessage()
class Win32Exception : public std::runtime_error
{
public:
Win32Exception() : std::runtime_error( ErrorMessage( &error_code_ ) )
{
};
virtual ~Win32Exception() { };
/// return the actual error code
DWORD ErrorCode() const throw() { return error_code_; };
private:
static std::string ErrorMessage( DWORD* error_code )
{
*error_code = ::GetLastError();
std::string error_messageA;
wchar_t* error_messageW = NULL;
DWORD len = ::FormatMessageW( FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
*error_code,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
reinterpret_cast< LPWSTR >( &error_messageW ),
0,
NULL );
if( NULL != error_messageW )
{
// this may generate a C4244 warning. It is safe to ignore.
std::copy( error_messageW,
error_messageW + len,
std::back_inserter( error_messageA ) );
::LocalFree( error_messageW );
}
return error_messageA;
};
/// error code returned by GetLastError()
DWORD error_code_;
}; // class Win32Exception
该类在其使用的情况下运行良好。我想要知道是否有明显的情况,这将会失败,我应该知道。请注意,boost库不是该代码的选项。
The class works well in the situations it has been used in. What I would like to know is if there are any obvious cases where this will fail that I should be aware of. Any other gotchas, caveats, or general suggestions on improvements are welcome.
b
推荐答案
- 这已经由几个人完成,包括你真正的
- This has already done by several people, including yours truly
- https://github.com/BillyONeal/Instalog/blob/master/LogCommon/Win32Exception.hpp
- https://github.com/BillyONeal/Instalog/blob/master/LogCommon/Win32Exception.cpp
讽刺的是,你的代码不是例外。
Ironically, your code is not exception safe.
if( NULL != error_messageW ) { // this may generate a C4244 warning. It is safe to ignore. std::copy( error_messageW, error_messageW + len, std::back_inserter( error_messageA ) ); ::LocalFree( error_messageW ); }
请注意, back_inserter
导致 std :: bad_alloc
被抛出,分配在 FormatMessage
被泄露。
Note that if the back_inserter
causes std::bad_alloc
to be thrown, the memory allocated inside FormatMessage
is leaked.
这篇关于将GetLastError()转换为异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!