Как работают СОМ-серверы
Созданный и подключенный компоновщиком динамически загружаемый модуль сервера система интегрирует в пространство другого (клиентского) процесса, загрузив его по определенному базовому адресу. Любая динамически загружаемая библиотека экспортирует функции, которые пишутся в расчете на то, что их будет вызывать клиентское приложение или другая DLL. Как только DLL спроецирована на адресное пространство вызывающего процесса, ее данные и функции становятся доступными клиенту и представляют собой просто дополнительный код и данные, как-то оказавшиеся в адресном пространстве процесса.
СОМ-серверы, которые хранятся в DLL-файлах, называются внутризадачными (in-process) серверами. Но они могут быть реализованы и в виде ЕХЕ-файлов. Тогда они называются либо локальными (local) серверами, либо удаленными (remote) серверами. Приложение-клиент и локальный сервер функционируют в отдельных процессах или адресных пространствах в рамках одной машины. Клиент и удаленный сервер функционируют не только в отдельных процессах (адресных пространствах), но и разделены сетевыми каналами связи.
И тем и другим необходим коммуникационный мост, чтобы вызывать функции и передавать друг другу данные. Такой мост обеспечивают библиотеки OLE, которые в качестве средства реализации используют механизм RFC (Remote Procedure Call – удаленный вызов процедуры)., Существует еще одна классификация СОМ или OLE-объектов. В рамках MFC и поддерживаемой ею архитектуры документ – представление мы можем создать объекты, которые либо поддерживают связь (linked) с приложением-контейнером, либо внедрены в него (embedded). Некоторые приложения поддерживают как связывание, так и внедрение объектов.
Основное различие между двумя типами OLE-объектов заключается в том, что источник данных внедренного (embedded) объекта является частью документа контейнера и хранится вместе с данными контейнера, в то время как данные связанного (linked) объекта хранятся в документе сервера, то есть в файле, созданном и управляемым сервером. Объект контейнера, который связан (linked), хранит лишь информацию, необходимую для связи с документом сервера. Говорят, что объект контейнера хранит связь с документом сервера. Приложение-сервер, поддерживающее связывание, должно уметь копировать свои данные в буфер обмена для выполнения нужд контейнера по копированию объекта.
Обычно под внедренным объектом понимается обобщенный объект, независимо от способа общения с ним (linked или embedded).
В конце этого урока мы (в рамках другой библиотеки – ATL) создадим DLL-сервер, который выполняет роль простейшего элемента ActiveX, внедряемого в окно приложения-клиента. Но сначала подробно рассмотрим, как взаимодействуют клиент и сервер в рамках приложения, использующего "сырые" (raw) функции COM API, с разработки которых и началось движение СОМ.