Сущность технологии СОМ. Библиотека программиста | страница 77
assert(SUCCEEDED(hr));
if (pszHelpFile) hr=pcei->SetHelpFile(constcast
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;
}
Заметим, что реализация метода заботится о том, чтобы не позволить чисто С++-исключениям переходить через границы метода. Таково безусловное требование СОМ.
Где мы находимся?
В этой главе была представлена концепция интерфейса СОМ. Интерфейсы СОМ обладают простыми двоичными сигнатурами, которые позволяют любому клиенту обращаться к объекту независимо от языка программирования, использованного клиентом или конструктором объекта. Чтобы облегчить поддержку различных языков, интерфейсы СОМ определяются на языке IDL (Interface Definition Language). Эти IDL-определения интерфейса могут быть также использованы для генерирования кода передачи данных (communications code), который позволяет получать доступ к объекту через сеть.
Большая часть этой главы была посвящена IUnknown – базовому интерфейсу, на котором построен весь СОМ. Все интерфейсы СОМ должны наследовать от IUnknown. Следовательно, все объекты СОМ должны реализовывать IUnknown. В IUnknown предусмотрено три сигнатуры метода, посредством которых клиент может безошибочно управлять иерархией типов объекта для доступа к дополнительным возможностям, предоставляемым этим объектом. С учетом этого