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

Из требования, чтобы множество поддерживаемых интерфейсов было статичным, следует простой вывод, что разработчикам объектов не разрешается создавать конструкции, состоящие из одного объекта, который дает два различных ответа «да/нет» на запрос определенного интерфейса. Одна из причин того, что иерархия типов объекта должна оставаться неизменной на всем протяжении своего жизненного цикла, состоит в том, что СОМ не гарантирует отправления всех клиентских запросов QueryInterface такому объекту в случае, когда к нему имеется удаленный доступ. Неизменность иерархии типов позволяет «заместителям» на стороне клиента (client-side proxies) кэшировать результаты QueryInterface во избежание чрезмерных обменов клиент-объект. Такая оптимизация очень важна для эффективности СОМ, но она разрушает конструкции, использующие QueryInterface для передачи динамической семантической информации вызывающему объекту.

<p>Единственность и идентификация</p>

Предыдущий раздел был посвящен запросам QueryInterface, которые представляют собой ответы типа «да/нет» вызывающим объектам. QueryInterface действительно возвращает S_OK (да) или E_NOINTERFACE (нет). Впрочем, когда QueryInterface возвращает S_OK, то он также возвращает объекту интерфейсный указатель. Для СОМ значение этого указателя чрезвычайно важно, так как оно позволяет клиентам определить, действительно ли на один и тот же объект указывают два интерфейсных указателя.

<p>QueryInterface и IUnknown</p>

Свойство рефлективности QueryInterface гарантирует, что любой интерфейсный указатель сможет удовлетворить запросы на IUnknown, поскольку все интерфейсные указатели неявно принадлежат к типу IUnknown. Спецификация СОМ имеет немного больше ограничений при описании результатов запросов QueryInterface именно на IUnknown. Объект не только должен отвечать «да» на запрос, он должен также возвращать в ответ на каждый запрос в точности одно и то же значение указателя. Это означает, что в следующем коде оба утверждения всегда должны быть верны:

void AssertSameObject(IUnknown *pUnk)

{

IUnknown *pUnk1 = 0,

*pUnk2 = 0;

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

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

// QueryInterface(IUnknown) must always succeed

// QueryInterface(IUnknown) должно всегда быть успешным

assert(SUCCEEDED(hr1) && SUCCEEDED(hr2));

// two requests for IUnknown must always yield the

// same pointer values

// два запроса на IUnknown должны всегда выдавать

// те же самые значения указателя

assert(pUnk1 == pUnk2);

pUnk1->Release();

pUnk2->Release();

}

Это требование позволяет клиентам сравнивать два любых указателя интерфейса для выяснения того, действительно ли они указывают на один и тот же объект.

bool IsSameObject(IUnknown *pUnk1, IUnknown *pUnk2)

{ assert(pUnk1 && pUnk2);

bool bResult = true;

if (pUnk1 != pUnk2)

{

HRESULT hr1, hr2; IUnknown *p1 = 0, *p2 = 0;

hr1 = pUnk1->QueryInterface(IID_IUnknown, (void **)&p1);

assert(SUCCEEDED(hr1));

hr2 = pUnk2->QueryInterface(IID_IUnknown, (void **)&p2);

assert(SUCCEEDED(hr2));

// compare the two pointer values, as these

// represent the identity of the object

// сравниваем значения двух указателей,

// так как они идентифицируют объект

bResult = (р1 == р2); p1->Release();

p2->Release();

}

return bResult;

}

В главе 5 будет рассмотрено, что понятие идентификации является фундаментальным принципом, так как он используется в архитектуре удаленного доступа СОМ с целью эффективно представлять интерфейсные указатели на объекты в сети.

Вооружившись знанием правил IUnknown, полезно исследовать реализацию объекта и убедиться в том, что она придерживается всех этих правил. Следующая реализация выставляет каждый из четырех интерфейсов средств транспорта и IUnknown:

class CarBoatPlane : public ICar, public IBoat, public IPlane

{

public:

// IUnknown methods – методы IUnknown

STDMETHODIMP QueryInterface(REFIID, void**);

STDMETHODIMP_(ULONG) AddRef(void);

STDMETHODIMP_(ULONG) Release(void);

// IVehicle methods – методы IVehicle

STDMETHODIMP GetMaxSpeed(long *pMax);

// ICar methods – методы

ICar STDMETHODIMP Brake(void);

// IBoat methods – методы

IBoat STDMETHODIMP Sink(void);

// IPlahe methods – методы

IPlane STDMETHODIMP TakeOff(void); };

Ниже приведена стандартная реализация QueryInterface в CarBoatPlane:

STDMETHODIMP QueryInterface(REFIID riid, void **ppv)

{

if (riid == IID_IUnknown) *ppv = static_cast(this);

else if (riid == IID_IVehicle) *ppv = static_cast(this);

else if (riid == IID_ICar) *ppv = static_cast(this);

else if (riid == IID_IBoat) *ppv = static_cast(this);

else if (riid == IID_IPlane) *ppv = static_cast(this);

else return (*ppv = 0), E_NOINTERFACE;

((IUnknown*)*ppv)->AddRef();

return S_OK;

}

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных