Модель программирования Component Object Model. Разработка COM-сервера, страница 2

Акт передачи данных (параметров функций и возвращаемых значений) за пределы процесса называется транспортировкой. Она включает в себя упаковку данных, передачу их за пределы процесса и распаковку данных по достижении ими места назначения. В COM надо транспортировать данные и интерфейсные указатели в процессах типа «клиент – локальный сервер».

Когда клиент вызывает метод локального сервера, этот вызов перехватывается частью кода, которая называется функцией-заместителем (proxy). Заместитель является представителем  настоящего сервера и располагается в адресном пространстве клиента. Заместитель получает вызов метода, упаковывает параметры, которые будут посланы локальному серверу, и вызывает соответствующий метод при помощи RPC.

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

Библиотеки OLE обеспечивают функции-заместители и функции-посредники для стандартных интерфейсов. При написании собственных интерфейсов для создания таких функций помогают специальные инструменты их разработки.

Разработка COM-сервера

Сейчас мы займемся разработкой DLL COM-сервера, выполняемого в пространстве процесса другого (клиентского) приложения. Для того, чтобы понять, что кроется за этой вывеской, создадим минимально-простой COM-объект и специально не будем пользоваться какими-либо библиотеками или инструментами студии.

Наш объект будет предоставлять миру только один интерфейс ISay, инкапсулирующий два метода: Say и SetWord. Первый метод выводит текстовую строку типа BSTR в окно MessageBox, а второй — позволяет изменять эту строку. Тип BSTR в Win32 является адресом двухбайтовой Unicode-строки. Его советуют использовать в COM-объектах для обеспечения совместимости c клиентскими приложениями, написанными на других языках.

Я надеюсь, что логика, заложенная в этом простом приложении, поможет вам не терять нить повествования при разработке следующего, более сложного объекта с помощью ATL. Использование ATL и инструментов студии упрощают разработку COM-объектов, но скрывают суть происходящего, вызывая иногда чувство досады и неудовлетворенности у пытливого разработчика. С помощью мастера AppWizard создайте шаблон приложения типа Win32 Dynamic-Link Library под именем MyCom.

1.  Дайте команду File4New4Project. В диалоге New Project выберите шаблон Win32 Project под именем MyCom и нажмите OK;

2.  В окне Win32 Application Wizard откройте вкладку Application Settings, установите переключатель Application Type в положение DLL, включите флажок Empty Project и нажмите кнопку Finish;

3.  Подключите к проекту новый файл типа C/C++ Header File. Для этого дайте команду Project4Add New Item. В диалоге Add New Item выберите шаблон Header File (.h), а в поле Name задайте имя guids и нажмите кнопку Open;

4.  Введите в файл guids.h нижеследующие директивы препроцессора и описание интерфейса ISay;

#pragma once // Эти директива не допускает повторное подключение файла

#include <windows.h> // COM API

#include <initguid.h>  // IUnknown

// Интерфейс ISay мы собираемся показать миру. Он, как и положено, происходит от IUnknown

// и содержит только чисто виртуальные функции

interface ISay : public IUnknown

{

//=== 2 метода, которые интерфейс предоставляет своим клиентам

virtual HRESULT __stdcall Say()=0;

virtual HRESULT __stdcall SetWord (BSTR word)=0;

};

Абстрактный интерфейс не может жить сам по себе. Он должен иметь класс-оболочку (wrapper class), который на деле реализует виртуальные методы Say и SetWord. Этот, так называемый ко-класс (класс COM-компонеты), производится от интерфейса ISay и предоставляет тела всем унаследованным (чисто) виртуальным методам своего родителя.