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


Приведение типов и IUnknown


В предыдущей главе обсуждалось, почему необходимо определять тип на этапе выполнения в динамически собранной системе. Язык C++ предусматривает разумный механизм для динамического определения типа с помощью оператора dynamic_cast. Хотя эта языковая возможность имеет собственную реализацию для каждого компилятора, в предыдущей главе было предложено средство урегулирования этого — добавление к каждому интерфейсу явного метода, являющегося семантическим эквивалентом dynamic_cast. Ниже приводится IDL-описание QueryInterface:

HRESULT QueryInterface([in] REFIID riid, [out] void **ppv);

Первый параметр (riid) является физическим именем запрошенного интерфейса. Второй параметр (ppv) указывает на переменную интерфейсного указателя, которая в случае успешного завершения будет содержать запрошенный указатель на интерфейс.

В ответ на запрос QueryInterface, если объект не поддерживает запрошенный тип интерфейса, он должен возвратить E_NOINTERFACE после установки *ppv в нулевое значение. Если же объект поддерживает запрошенный интерфейс, он должен перезаписать *ppv указателем запрошенного типа и возвратить HRESULT S_OK. Поскольку ppv является [out]-параметром, реализация QueryInterface должна выполнить AddRef для возвращаемого указателя перед тем, как вернуть управление вызывающему объекту (см. в этой главе выше руководящий принцип А2). Этот вызов AddRef должен быть согласован с вызовом Release со стороны клиента. Следующий код показывает динамическое определение типа с использованием оператора C++ dynamic_cast на примере иерархии типов Dog/Cat, описанного ранее в данной главе:

void TryToSnoreAndIgnore(/* [in] */ IUnknown *pUnk) { IPug *pPug = 0; pPug = dynamic_cast<IPug*> (pUnk); if (pPug) // the object is Pug-compatible // объект совместим с Pug pPug->Snore(); ICat *pCat = 0; pCat = dynamic_cast<ICat*>(pUnk); if (pCat) // the object is Cat-compatible // объект совместим с Cat pCat-> IgnoreMaster(); }

Если объект, переданный этой функции, совместим одновременно с ICat и с IDog, то задействованы обе функциональные возможности.


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



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