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



         

Управление жизненным циклом и маршалинг - часть 7


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

STDMETHODIMP Monitor::GetSample(/*[out]*/ SAMPLEDATA *ps) { HRESULT hr = this->GetSampleFromProbe(ps); if (FAILED(hr)) // probe or object may be corrupted // образец или объект могут быть испорчены CoDisconnectObject(this, 0); return hr; }

Функция CoDisconnectObject используется также в случаях, когда процесс хочет отключиться, хотя один или более его объектов могут иметь неосвобожденные заместители. При явном вызове CoDisconnectObject до уничтожения любых объектов, которые могут иметь оставшиеся заместители, нет риска, что исходящие ORPC-запросы будут обслуживаться после того, как объект уже уничтожен. Если бы входящий ORPC-запрос должен был бы поступить после того, как объект уже уничтожен, но администратор заглушек еще жив, то небрежность привела бы к вызову интерфейсной заглушкой соответствующего метода из участка памяти, ранее известного как данный объект. Это вызвало бы лишние неприятности, связанные с тщетными усилиями по отладке.

Обе функции - 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 // зарезервировано, должно быть равно нулю );




Содержание  Назад  Вперед