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

Единственными допустимыми значениями счетчика являются нуль (это означает, что данный объект не содержит описаний своего интерфейса) и единица (это означает, что данный объект содержит описания своего интерфейса). Даже если объект поддерживает несколько локализованных описаний типа, результирующий счетчик остается равным единице.

Методы GetTypeInfo и GetTypeInfoCount фактически являются вспомогательными. Истинным ядром интерфейса IDispatch являются методы GetIDsOfNames и Invoke. Реализация GetIDsOfNames направляет вызов в машину синтаксического анализа библиотеки типов, встроенную в СОМ:

STDMETHODIMP PrimeManager::GetIDsOfNames(REFIID riid, OLECHAR **pNames, UINT cNames, LCID lcid, DISPID *pdispids) {

assert(riid == IID_NULL);

return m_pTypeInfo->GetIDsOfNames(pNames, cNames, pdispids);

}

Поскольку библиотека типов содержит все имена методов и соответствующие им DISPID , реализация не представляет труда для синтаксического анализатора. Метод Invoke реализован аналогичным образом:

STDMETHODIMP PrimeManager::Invoke(DISPID id, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pd, VARIANT *pVarResult, EXCEPINFO *pe, UINT *pu) {

assert(riid == IID_NULL);

void *pvThis = static_cast(this);

return m_pTypeInfo->Invoke(pvThis, id, wFlags, pd, pVarResult, pe, pu);

}

Первым параметром ITypeInfo::Invoke является указатель на интерфейс. Тип этого интерфейса должен быть таким же, как интерфейс, который описан в информации о типах. Когда передаваемые аргументы корректно синтаксически преобразованы в стек вызова (call stack), синтаксический анализатор будет вызывать текущие методы через этот интерфейсный указатель. Рис. 7.6 иллюстрирует последовательность вызовов для сред подготовки сценариев, которые осуществляют вызовы через двойственные интерфейсы.

<p>Двунаправленные интерфейсные контракты</p>

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

Как два объекта договариваются о том, чьи интерфейсы будут использоваться для взаимного сотрудничества, в значительной степени является спецификой области применения. Для примера рассмотрим следующий интерфейс, моделирующий программиста:

[uuid(75DA6457-DD0F-11d0-8C58-0080C73925BA),object]

interface IProgrammer : IUnknown {

HRESULT StartHacking(void);

HRESULT IsProductDone([out, retval] BOOL *pbIsDone);

}

Клиент будет использовать такой интерфейс следующим образом:

HRESULT ShipSoftware(void)

{

IProgrammer *pp = 0;

HRESULT hr = CoGetObject(OLESTR(«programmer:Bob»), 0,

IID_IProgrammer, (void**)&pp);

if (SUCCEEDED(hr)) {

hr = pp->StartHacking();

BOOL bIsDone = FALSE;

while (!bIsDone && SUCCEEDED(hr)) {

Sleep(15000);

// wait 15 seconds

// ожидаем 15 секунд

hr = pp->IsProductDone(&bIsDone);

// check status

// проверяем состояние

}

pp->Release();

}

}

Очевидно, что этот код весьма неэффективен, поскольку клиент каждые 15 секунд опрашивает состояние объекта. Более эффективным для клиента был бы следующий подход: подготовить второй объект, которому объект-программист (programmer object) мог бы сообщить, когда данный объект придет в нужное состояние. Этот подготовленный клиентом объект должен экспортировать интерфейс, предоставляющий контекст, через который мог бы работать объект-программист:

[uuid(75DA6458-DD9F-11d0-8C58-0080C73925BA),object]

interface ISoftwareConsumer : IUnknown {

HRESULT OnProductIsDone(void);

HRESULT OnProductWillBeLate([in] hyper nMonths);

}

При таком парном определении интерфейса должен существовать некий механизм для информирования объекта-программиста о том, что у клиента имеется реализация ISoftwareConsumer, с помощью которой он может получать уведомления от объекта-программиста об изменениях состояния. Одной из распространенных методик является определение IProgrammer таким образом, чтобы он имел явные методы, через которые клиенты могли бы связываться со своими объектами-потребителями (consumer object). Канонической формой этой идиомы является включение метода Advise:

interface IProgrammer : IUnknown {

HRESULT Advise ([in] ISoftwareConsumer *psc, [out] DWORD *pdwCookie);

: : :

посредством которого клиент подготавливает парный объект-потребитель, а программист возвращает DWORD для подтверждения связи. Затем этот DWORD можно было бы использовать в соответствующем методе Unadvise:

interface IProgrammer : IUnknown {

: : :

HRESULT Unadvise([in] DWORD dwCookie);

}

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

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

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

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

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

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

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

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

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