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



Из того, что все объекты СОМ имеют статическую иерархию типов, следует, что утверждение, записанное в следующем коде, никогда не должно быть ложным, несмотря на то, что идентификатор интерфейса используется в качестве второго параметра:


void AssertStaticType(IUnknown *pUnk, REFIID riid)

{

IUnknown *pUnk1 = 0,

*pUnk2 = 0;

HRESULT hr1 = pUnk->QueryInterface(riid, (void**)&pUnk1);

HRESULT hr2 = pUnk->QueryInterface(riid, (void**)&pUnk2);

// both requests for the same interface should

// yield the same yes/no answer

// оба запроса того же самого интерфейса

// должны получить тот же самый ответ да/нет

assert(SUCCEEDED(hr1) == SUCCEEDED(hr2));

if (SUCCEEDED(hr1)) pUnk1->Release();

if (SUCCEEDED(hr2)) pUnk2->Release();

}


Это требование означает, что в СОМ запрещены следующие программные технологии:


Использование временной информации при решении вопроса о том, удовлетворять или нет запрос QueryInterface (например, выдавать интерфейс IMorning (утро) только до 12:00).

Использование переменной информации о состоянии при решении вопроса о том, удовлетворять или нет запрос QueryInterface (например, выдавать интерфейс INotBusy (не занят), только если количество внешних интерфейсных указателей меньше десяти).

Использование маркера доступа (security token) вызывающего объекта для решения, удовлетворять или нет запрос QueryInterface . Как будет объяснено в главе 6, на самом деле это не обеспечивает никакой реальной безопасности из-за протокола передачи (wire protocol ), используемого СОМ.

Использование успешного захвата динамических ресурсов для решения вопроса о том, удовлетворять или нет запрос QueryInterface (например, выдавать интерфейс IHaveTonsOfMemory (у меня тонны памяти) только при успешном выполнении malloc(4096*4096)).


Эта последняя методика может быть до некоторой степени смягчена, если разработчик объекта желает поупражняться с выражением спецификации СОМ «barring catastrophic failure» (за исключением катастрофического сбоя).

Эти ограничения не означают, что два объекта одного и того же класса реализации не могут давать различные ответы «да/нет» при запросе одного и того же интерфейса. Например, класс может реализовать показанные ранее интерфейсы ICar, IBoat и IPlane , но может разрешить только одному интерфейсу быть использованным в каком-то определенном объекте. Эти ограничения также не означают, что объект не может использовать постоянную или временную информацию для решения вопроса о том, дать ли