#include <comdef.h>Типичный адаптер для обработки ошибок COM. Не помешает иметь такой же адаптер для не-COM функций:
inline void TESTHR(HRESULT hr)
{
if (FAILED(hr))
_com_issue_error(hr);
};
...
TESTHR(::CoCreateGuid(&UniqueID));
#include <windows.h>Единственное - не хватает того самого класса WindowsError.
inline void TestWinFn(BOOL WindowsFunctionResult)
{
if (!WindowsFunctionResult)
throw WindowsError(::GetLastError());
}
...
TestWinFn(::ConvertSidToStringSid(SID, &StringSID));
#include <windows.h>
#include <exception>
#include <Loki/ScopeGuard.h>
class WindowsError : public std::exception
{
public:
WindowsError(DWORD ErrorCode = ::GetLastError())
std::exception(Message(ErrorCode).c_str()),
_ErrorCode(ErrorCode) {}
DWORD ErrorCode() const { return _ErrorCode; }
private:
static std::wstring Message(DWORD ErrorCode)
{
std::wstring Result;
LPVOID Buffer = NULL;
if (::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
ErrorCode,
0, // Default language
(LPTSTR) &Buffer,
0,
NULL))
{
LOKI_ON_BLOCK_EXIT(LocalFree, Buffer);
Result.assign((LPCWSTR)Buffer);
}
return Result;
}
private:
DWORD _ErrorCode;
};
PS. Кто не использует Loki - сюда.
2 комментария:
Тут есть одна проблема. Бросать исключения на каждый вызов во-первых дорого, а во-вторых идеологически не совсем правильно. Бросать нужно только тогда, когда возникла "непредвиденная" ситуация. Например CreateFile, возвращающий File not found в большинстве случаев не является непредвиденной ситуацией и такое эффективнее обрабатывать проверяя код ошибки.
Бросать исключения следует тогда, когда не знаешь что делать с ошибкой. Тогда просто отправляешь ее с помощью механизма исключений вверх по служебной лестнице, а там разберутся.
Если понятно что делать с ошибкой, то бросать исключение не надо, ты верно заметил.
Вобщем, голову на плечах иметь никто не отменял ;)
Отправить комментарий