Сущность технологии COM


Исключения - часть 3


Отметим, что поскольку объект исключений передается в процедуру SetErrorInfo, СОМ сохраняет ссылку на исключение до тех пор, пока оно не будет "перехвачено" вызывающим объектом, использующим GetErrorInfo.

Объекты, которые сбрасывают исключения СОМ, должны использовать интерфейс ISupportErrorInfo, чтобы показывать, какие интерфейсы поддерживают исключения. Этот интерфейс используется клиентами, чтобы установить, верный ли результат дает GetErrorInfo. Этот интерфейс предельно прост:

[ object, uuid(DFOB3060-548F-101B-8E65-08002B2BD119) ] interface ISupportErrorInfo: IUnknown { HRESULT InterfaceSupportsErrorInfo([in] REFIID riid); }

Предположим, что класс PugCat, рассмотренный в этой главе, сбрасывает исключения из каждого поддерживаемого им интерфейса. Тогда его реализация будет выглядеть так:

STDMETHODIMP PugCat::InterfaceSupportsErrorInfo(REFIID riid) { if (riid == IID_IAnimal riid == IID_ICat riid == IID_IDog riid == IID_IPug) return S_OK; else return S_FALSE; }

Ниже приведен пример клиента, который надежно обрабатывает исключения, используя ISupportErrorInfo и GetErrorInfo:

void TellPugToSnore(/*[in]*/ IPug *pPug) { // call a method // вызываем метод HRESULT hr = pPug->Snore(); if (FAILED(hr)) { // check to see if object supports СОМ exceptions // проверяем, поддерживает ли объект исключения СОМ ISupportErrorInfo *psei = 0; HRESULT hr2 =pPug->QueryInterface( IID_ISupportErrorInfo, (void**)&psei); if (SUCCEEDED(hr2)) { // check if object supports СОМ exceptions via IPug methods // проверяем, поддерживает ли объект исключения СОМ через методы IPug hr2 = psei->InterfaceSupportsErrorInfo(IID_IPug); if (hr2 == S_OK) { // read exception object for this logical thread // читаем объект исключений для этого логического потока IErrorInfo *реi = 0; hr2 = GetErrorInfo(0, &pei); if (hr2 == S_OK) { // scrape out source and description strings // извлекаем строки кода и описания BSTR bstrSource = 0, bstrDesc = 0; hr2 = pei->GetDescription(&bstrDesc); assert(SUCCEEDED(hr2)); hr2 = pei->GetSource(&bstrSource); assert(SUCCEEDED(hr2)); // display error information to end-user // показываем информацию об ошибке конечному пользователю MessageBoxW(0, bstrDesc ? bstrDesc : L"", bstrSource ? bstrSource : L"", MB_OK); // free resources // высвобождаем ресурсы SysFreeString(bstrSource); SysFreeString(bstrDesc); pei->Release(); } } psei->Release(); } } if (hr2 != S_OK) // something went wrong with exception // что-то неладно с исключением MessageBox(0, "Snore Failed", "IPug", MB_OK); }




Начало  Назад  Вперед



Книжный магазин