Чтение онлайн

на главную - закладки

Жанры

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

Обе функции – CoLockObjectExternal и CoDisconnectObject – могут быть использованы разработчиком объектов для манипулирования администратором заглушек. Часто бывает полезно знать, есть ли в администраторе заглушек в наличии какие-либо заместители или объектные ссылки, маршалированные по сильной таблице (strong marshals ). Для информирования объектов о том, что имеются неосвобожденные внешние ссылки на администратор заглушек, в СОМ определен интерфейс IExternalConnection , который может быть экспортирован объектами:

[ uuid(00000019-0000-0000-C000-000000000046), object, local ]

interface IExternalConnection : IUnknown {

DWORD AddConnection(

[in] DWORD extconn,

// type of reference

//

тип ссылки

[in] DWORD reserved

// reserved, must be zero

// зарезервировано, должно быть равно нулю

);

DWORD ReleaseConnection(

[in] DWORD extconn,

// type of reference

// тип ссылки

[in] DWORD reserved,

// reserved, must be zero

// зарезервировано, должно быть равно нулю

[in] BOOL fLastReleaseCloses

// should kill stub?

// нужно ли убить заглушку?

); }

При первом подсоединении администратора заглушек к объекту он спрашивает объект, желает ли тот, чтобы его уведомляли о создании или уничтожении внешних ссылок. Он делает это посредством запроса интерфейса IExternalConnection для QueryInterface. Если объект не реализует IExternalConnection, то администратор заглушек будет использовать свой собственный счетчик ссылок при решении вопроса, когда уничтожать администратор заглушек. Если же объект предпочтет реализовать IExternalConnection, то в этом случае администратор заглушек будет жить до тех пор, пока объект явно не уничтожит его путем вызова CoDisconnectObject.

Ожидается, что в объектах, которые реализуют IExternalConnection, поддерживается счетчик блокировок, записывающий число вызовов функций AddConnection и ReleaseConnection. Для большей эффективности СОМ не вызывает AddConnection всякий раз, когда создается заместитель. Это означает, что если объект поддерживает счетчик блокировок, основанный на вызовах функций AddConnection и ReleaseConnection, то этот счетчик блокировок объекта не будет точно отражать число существующих в данный момент объектных ссылок. В то же время СОМ гарантирует, что в том случае, когда счетчик блокировок не равен пулю, существует хотя бы одна неосвобожденная ссылка, а если счетчик блокировок равен нулю, то не существует ни одной неосвобожденной ссылки. Вызовы функции CoLockObjectExternal также будут влиять на этот счетчик. Эта информация особенно полезна для тех объектов, которые заботятся о существовании внешних клиентов. Предположим для примера, что представленный ранее объект для контроля над аппаратным устройством порождает подпроцесс для выполнения фоновой регистрации выборочных данных. Также допустим, что если регистрация произойдет в тот момент, когда объект осуществляет активный контроль данных или, напротив, находится под контролем внешних клиентов, то может возникнуть ошибка выборки. Для предотвращения этой ситуации регистрационный поток мог бы проверять счетчик блокировок, поддерживаемый объектной реализацией IExternalConnection и осуществлять операцию регистрации только тогда, когда не существует внешних ссылок. Это предполагает, что объект реализует IExternalConnection следующим образом:

class Monitor : public IExternalConnection, public IMonitor {

LONG m_cRef;

// normal COM reference count

// обычный счетчик ссылок СОМ

LONG m_cExtRef;

// external reference count

//

счетчик внешних ссылок

Monitor(void) : m_cRef(0), m_cExtRef(0) { … }

STDMETHODIMP_(DWORD) AddConnection(DWORD extconn, DWORD) {

if (extconn & EXTCONN_STRONG)

// must check for this bit

// нужно проверить этот бит

return InterlockedIncrement(&m_cExtRef);

}

STDMETHODIMP_(DWORD) ReleaseConnection(DWORD extconn, DWORD,

BOOL bLastUnlockKillsStub) {

DWORD res = 0;

if (extconn & EXTCONN_STRONG) {

// must check for this bit

// нужно проверить этот бит

res = InterlockedDecrement(&m_cExtRef);

if (res == 0 && bLastUnlockKillsStub)

CoDisconnectObject(this, 0);

}

return res;

} }

: : :

: : : }

Получив эту реализацию, подпрограмма потока могла бы проверить состояние объекта и решить, выполнять или нет операцию регистрации, основываясь на уровне активности объекта:

DWORD WINAPI ThreadProc(void *pv) {

// assume ptr to real object is passed to CreateThread

// пусть указатель на действительный объект передается в CreateThread

Monitor *pm = (Monitor*)pv;

while (1) {

// sleep for 10 seconds

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

Sleep(1OOOO);

// if object is not in use, perform a log operation

// если объект не используется, то выполняем операцию регистрации

if (pm->m_cExtRef == 0)

pm->TryToLogSampleData;

}

return 0; }

Если принять, что метод объекта TryToLogSampleData корректно поддерживает параллелизм, то данная поточная процедура будет регистрировать данные только при условии, что объект не используется внешними клиентами или не осуществляет активный контроль (напомним, что при контроле объект увеличивает счетчик внешних ссылок посредством CoLockObjectExternal). Хотя данный пример может показаться несколько запутанным, имеются случаи, когда отслеживание внешних ссылок является решающим для обеспечения правильности операции. Один классический пример описан в главе 6 и относится к регистрации объектов класса на внепроцессных серверах.

Специальный маршалинг

До сих пор внимание в данной главе было сосредоточено на стандартном маршалинге и вызове методов на основе ORPC. Для большого класса объектов этого было достаточно, чтобы достичь нужного баланса между производительностью, семантической корректностью и простотой реализации. В то же время существуют объекты, для которых ORPC-вызов по умолчанию является неэффективным и даже непригодным. Для таких объектов в СОМ предусмотрен специальный маршалинг (custom marshaling). Как уже упоминалось в этой главе, специальный маршалинг позволяет разработчику объекта обеспечить реализацию специальных заместителей (custom proxies ), которые будут созданы в импортирующих апартаментах. Объекты сообщают о своем желании поддерживать специальный маршалинг путем экспорта интерфейса IMarshal:

[uuid(00000003-0000-0000-C000-000000000046), local, object] interface IMarshal : IUnknown {

// get CLSID for custom proxy (CoMarshalInterface)

// получаем CLSID для специального заместителя (CoMarshalInterface)

HRESULT GetUnmarshalClass( [in] REFIID riid, [in, iid_is(riid) ] void *pv, [in] DWORD dwDestCtx, [in] void *pvDestCtx, [in] DWORD mshlflags, [out] CLSID *pclsid);

// get size of custom marshaled objref (CoGetMarshalSizeMax)

// получаем размер специально маршалированной объектной ссылки (CoGetMarshalSizeMax)

Поделиться:
Популярные книги

Вечный. Книга II

Рокотов Алексей
2. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга II

Невеста на откуп

Белецкая Наталья
2. Невеста на откуп
Фантастика:
фэнтези
5.83
рейтинг книги
Невеста на откуп

Журналист

Константинов Андрей Дмитриевич
3. Бандитский Петербург
Детективы:
боевики
8.41
рейтинг книги
Журналист

Возвышение Меркурия. Книга 3

Кронос Александр
3. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 3

Завод 2: назад в СССР

Гуров Валерий Александрович
2. Завод
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Завод 2: назад в СССР

Охота на попаданку. Бракованная жена

Герр Ольга
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Охота на попаданку. Бракованная жена

На границе империй. Том 4

INDIGO
4. Фортуна дама переменчивая
Фантастика:
космическая фантастика
6.00
рейтинг книги
На границе империй. Том 4

Бракованная невеста. Академия драконов

Милославская Анастасия
Фантастика:
фэнтези
сказочная фантастика
5.00
рейтинг книги
Бракованная невеста. Академия драконов

Я еще не князь. Книга XIV

Дрейк Сириус
14. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я еще не князь. Книга XIV

Сорняк - 2

Буянов Андрей
Старинная литература:
прочая старинная литература
5.82
рейтинг книги
Сорняк - 2

Единственная для невольника

Новикова Татьяна О.
Любовные романы:
любовно-фантастические романы
5.67
рейтинг книги
Единственная для невольника

ВоенТур 3

АЗК
3. Антиблицкриг
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
ВоенТур 3

Если твой босс... монстр!

Райская Ольга
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Если твой босс... монстр!

Корпулентные достоинства, или Знатный переполох. Дилогия

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.53
рейтинг книги
Корпулентные достоинства, или Знатный переполох. Дилогия