Дональд Бокс - Сущность технологии СОМ. Библиотека программиста
- Название:Сущность технологии СОМ. Библиотека программиста
- Автор:
- Жанр:
- Издательство:Питер
- Год:2001
- Город:СПб
- ISBN:5-318-00058-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дональд Бокс - Сущность технологии СОМ. Библиотека программиста краткое содержание
В этой книге СОМ исследуется с точки зрения разработчика C++. Написанная ведущим специалистом по модели компонентных объектов СОМ, она раскрывает сущность СОМ, помогая разработчикам правильно понять не только методы модели программирования СОМ, но и ее основу. Понимание мотивов создания СОМ и ее аспектов, касающихся распределенных систем, чрезвычайно важно для тех разработчиков, которые желают пойти дальше простейших приложений СОМ и стать по-настоящему эффективными СОМ-программистами. Показывая, почему СОМ для распределенных систем (Distributed СОМ) работает именно так, а не иначе, Дон Бокс дает вам возможность применять эту модель творчески и эффективно для ежедневных задач программирования.
Сущность технологии СОМ. Библиотека программиста - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Как уже рассматривалось в главе 3, процессы могут контактировать с SCM для связывания ссылок на объекты класса, экземпляров класса и постоянных экземпляров. Для осуществления этого в COM предусмотрены три функции активации ( CoGetClassObject , CoCreateInstanceEx и CoGetInstanceFromFile ). Они, как и высокоуровневые моникеры, предназначены для того, чтобы скрыть детали реализации каждой стратегии связывания. В каждой из этих трех стратегий активации для вызова объекта к жизни используется объект класса. Как уже рассматривалось в главе 3, когда активация объекта осуществляется внутри процесса, DLL класса загружается самой COM, а для выборки соответствующих объектов класса используется известная точка входа DllGetClassObject . Однако пока не рассматривалось, как объекты могут быть активированы через границы процессов.
Процесс становится серверным процессом для определенного класса после явной саморегистрации с помощью SCM. После такой регистрации любые активационные запросы класса, для которых необходима внепроцессная активация, будут отосланы к зарегистрированному серверному процессу [2]. Серверные процессы саморегистрируются с помощью SCM API-функции CoRegisterClassObject :
HRESULT CoRegisterClassObject(
[in] REFCLSID rclsid,
// which class?
// какой класс?
[in] IUnknown *pUnkClassObject,
// ptr to class object
// указатель на объект класса
[in] DWORD dwClsCtx,
// locality
// локализация
[in] DWORD dwRegCls,
// activation flags
// флаги активации
[out] DWORD *pdwReg);
// association ID
// ID связи
При вызове CoRegisterClassObject библиотека COM сохраняет ссылку на объект класса, указанную в качестве второго параметра, и связывает объект класса с его CLSID в организованной внутри библиотеки таблице. В зависимости от флагов активации, использованных при вызове, библиотека COM может также сообщать локальному SCM, что вызывающий процесс является теперь серверным процессом для указанного класса. CoRegisterClassObject возвращает двойное слово (DWORD), которое представляет связь между CLSID и объектом класса. Это двойное слово можно использовать для завершения связи (а также для извещения SCM о том, что вызывающий процесс более не является серверным процессом для данного CLSID) путем вызова API-функции CoRevokeClassObject :
HRESULT CoRevokeClassObject([in] DWORD dwReg);
// association ID
// ID связи
Два параметра типа DWORD являются примером тонкого устройства CoRegisterClassObject . Эти параметры дают вызывающему объекту контроль над тем, как и когда объект класса является доступным.
А каким образом и на какой срок сделать доступным объект класса, вызывающему объекту позволяют решить флаги активации, передающиеся CoRegisterСlassObject в качестве четвертого параметра. COM предусматривает следующие константы для использования в этом параметре:
typedef enum tagREGCLS {
REGCLS_SINGLEUSE = 0,
// give out class object once
// выделяем объект класса однократно
REGCLS_MULTIPLEUSE = 1,
// give out class object many
// выделяем объект класса многократно
REGCLS_MULTI_SEPARATE = 2,
// give out class object many
// выделяем объект класса многократно
REGCLS_SUSPENDED = 4,
// do not notify SCM (flag)
// не извещаем SCM (флаг) REGCLS_SURROGATE = 8 // used with DLL Surrogates // используется с суррогатами DLL } REGCLS;
Значение REGCLS_SURROGATE используется в реализациях суррогатов DLL, которые будут рассматриваться позднее в данной главе. Двумя основными значениями являются REGCLS_SINGLEUSE и REGCLS_MULTIPLEUSE . Первое предписывает библиотеке COM использовать объект класса для обслуживания только одного активационного запроса. Когда происходит первый активационный запрос, COM удаляет зарегистрированный объект класса из области открытой видимости (public view). Если придет второй активационный запрос, COM должна использовать другой зарегистрированный объект класса. Если больше не доступен ни один объект класса с тем же CLSID, то для удовлетворения этого запроса COM создаст другой серверный процесс.
Напротив, флаг REGCLS_MULTIPLEUSE показывает, что объект класса может быть использован многократно, до тех пор, пока вызов функции CoRevokeСlassObject не удалит его элемент из таблицы класса библиотеки COM. Флаг REGCLS_MULTI_SEPARATE адресует последующие внутрипроцессные активационные запросы, которые могут произойти в процессе вызывающего объекта. Если вызывающий объект регистрирует объект класса с флагом REGCLS_MULTIPLEUSE , то COM допускает, что любые внутрипроцессные активационные запросы от процесса вызывающего объекта не будут загружать отдельный внутрипроцессный сервер, а будут вместо этого использовать зарегистрированный объект класса. Это означает, что даже если вызывающая программа только зарегистрировала объект класса с флагом CLSCTX_LOCAL_SERVER , то для удовлетворения внутрипроцессных запросов от того же процесса будет использован зарегистрированный объект класса. Если такое поведение неприемлемо, вызывающая программа может зарегистрировать объект класса, используя флаг REGCLS_MULTI_SEPARATE . Флаг инструктирует COM использовать зарегистрированный объект класса для внутрипроцессных запросов только в случае, если для регистрации этого класса был использован флаг CLSCTX_INPROC_SERVER . Это означает, что следующий вызов CoRegisterClassObject :
hr = CoRegisterClassObject(CLSID_Me, &g_coMe, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dw);
эквивалентен следующему:
hr = CoRegisterClassObject(CLSID_Me, &g_coMe, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC, REGCLS_MULTI_SEPARATE, &dw);
В любом случае, если бы из процесса вызывающего объекта был осуществлен такой вызов:
hr = CoGetClassObject(CLSID_Me, CLSCTX_INPROC, 0, IID_IUnknown, (void**)&pUnkCO);
то никакая DLL не была бы загружена. Вместо этого COM удовлетворила бы запрос, используя объект класса, зарегистрированный посредством CoRegisterClassObject . Если, однако, серверный процесс вызвал CoRegisterClassObject таким образом:
hr = CoRegisterClassObject(CLSID_Me, &g_coMe, CLSCTX_LOCAL_SERVER, REGCLS_MULTI_SEPARATE, &dw);
то любые внутрипроцессные запросы на активацию CLSID_Me , исходящие изнутри серверного процесса, заставят DLL загрузиться.
CoRegisterClassObject связывает зарегистрированный объект класса с апартаментом вызывающего объекта. Это означает, что все поступающие запросы методов будут выполняться в апартаменте вызывающей программы. В частности, это означает, что если объект класса экспортирует интерфейс IClassFactory , то метод CreateInstance будет выполняться в апартаменте вызывающей программы. Результаты метода CreateInstance будут маршалированы из апартамента объекта класса, а это, в свою очередь, означает, что экземпляры класса будут принадлежать к тому же апартаменту, что и объект класса [3].
Серверные процессы могут регистрировать объекты класса для более чем одного класса. Если объекты класса зарегистрированы для выполнения в МТА процесса, то это означает, что поступающие запросы на активацию могут быть обслужены, как только будет завершен первый вызов CoRegisterClassObject . Во многих серверных процессах, основанных на МТА, это может вызвать проблемы, так как бывает, что процесс должен выполнить дальнейшую инициализацию. Чтобы избежать этой проблемы, в реализации COM под Windows NT 4.0 введен флаг REGCLS_SUSPENDED . При добавлении этого флага в вызов CoRegisterСlassObject библиотека COM не извещает SCM о том, что класс доступен. Это предотвращает поступление в серверный процесс входящих активационных запросов. Библиотека COM связывает CLSID с объектом класса; однако она помечает этот элемент в таблице библиотеки класса как отложенный. Для снятия этой пометки в COM предусмотрена API-функция CoResumeClassObjects :
Читать дальшеИнтервал:
Закладка: