Сущность технологии СОМ. Библиотека программиста

ОглавлениеДобавить в закладки К обложке

}

Довольно просто отобразить исключения СОМ в исключения C++, причем в любом месте. Определим следующий класс, который упаковывает объект исключений СОМ и HRESULT в один класс C++:

struct COMException

{

HRESULT mhresult;

// hresult to return

// hresult для возврата IErrorInfo *mpei;

// exception to throw

// исключение для выбрасывания

COMException(HRESULT hresult, REFIID riid, const OLECHAR *pszSource, const OLECHAR *pszDesc, const OLECHAR *pszHelpFile = 0, DWORD dwHelpContext = 0)

{

// create and init an error info object

// создаем и инициализируем объект информации об ошибке

ICreateErrorInfo *рсеi = 0;

HRESULT hr = CreateErrorInfo(&pcei);

assert(SUCCEEDED(hr));

hr = pcei->SetGUID(riid);

assert(SUCCEEDED(hr));

if (pszSource) hr=pcei->SetSource(constcast<OLECHAR*>(pszSource));

assert(SUCCEEDED(hr));

if (pszDesc) hr=pcei->SetDescription(constcast<OLECHAR*>(pszDesc));

assert(SUCCEEDED(hr));

if (pszHelpFile) hr=pcei->SetHelpFile(constcast<OLECHAR*>(pszHelpFile));

assert(SUCCEEDED(hr));

hr = pcei->SetHelpContext(dwHelpContext);

assert(SUCCEEDED(hr));

// hold the HRESULT and IErrorInfo ptr as data members

// сохраняем HRESULT и указатель IErrorInfo как элементы данных

mhresult = hresult;

hr=pcei->QueryInterface(IIDIErrorInfo, (void**)&mpei);

assert(SUCCEEDED(hr));

pcei->Release();

}

};

С использованием только что приведенного С++-класса COMException показанный выше метод Snore может быть модифицирован так, чтобы он преобразовывал любые исключения C++ в исключения СОМ:

STDMETHODIMP PugCat::Snore(void)

{

HRESULT hrex = SOK;

try

{

if (this->IsAsleep()) return this->DoSnore();

else throw COMException(PUGEPUGNOTASLEEP, IIDIPug, OLESTR(«PugCat»), OLESTR(«I am not asleep!»));

}

catch (COMException& ce)

{

// a C++ COMException was thrown

// было сброшено исключение COMException C++

HRESULT hr = SetErrorInfo(0, ce.mpei);

assert(SUCCEEDED(hr));

ce.mpei->Release();

hrex = ce.mhresult;

}

catch (…)

{

// some unidentified C++ exception was thrown

// было выброшено какое-то неидентифицированное исключение C++

COMException ex(EFAIL, IIDIPug, OLESTR(«PugCat»), OLESTR(«A C++ exception was thrown»));

HRESULT hr = SetErrorInfo(0, ex.mpei);

assert(SUCCEEDED(hr));

ex.mpei->Release();

hrex = ex.mhresult;

}

return hrex;

}

Заметим, что реализация метода заботится о том, чтобы не позволить чисто С++-исключениям переходить через границы метода. Таково безусловное требование СОМ.


Логин
Пароль
Запомнить меня