Учебник по Visual C++ .Net


Как работают СОМ-серверы Созданный


MY__ISAY_INTERFACE

#pragma once

//====== Для того, чтобы были доступны COM API

#include <windows.h>

//====== Для того, чтобы был виден lUnknown

#include <initguid.h>

// Интерфейс ISay мы собираемся зарегистрировать и

// показать миру. Он, как и положено, происходит от

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

interface ISay : public lUnknown

{

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

//=== предоставляет своим клиентам

virtual HRESULT _stdcall Say 0=0;

virtual HRESULT _stdcall SetWord (BSTR word)=0;

}

#endif

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

Как работают СОМ-серверы Созданный
Если вы хотите, чтобы класс реализовывал несколько интерфейсов, то вы должны использовать множественное наследование. Такой подход проповедует ATL (Active Template Library). MFC реализует другой подход к реализации интерфейсов. Он использует вложенные классы. Каждому интерфейсу соответствует новый класс, вложенный в один общий класс СОМ-объекта.

Для того чтобы быть доступным тем приложениям, которые захотят воспользоваться услугами СОМ-объекта, сам класс тоже должен иметь дом (в виде inproc-сервера DLL). Сейчас, разрабатывая проект типа Win32 DLL, мы строим именно этот дом. С помощью механизма DLL класс будет доступен приложению-клиенту, в адресное пространство процесса которого он загружается. Вы знаете, что DLL загружается в пространство клиента только при необходимости.

Нам неоднократно понадобятся услуги инструмента Studio.Net под именем GuidGen, поэтому целесообразно ввести в меню Tools (Инструментальные средства) Studio.Net новую команду для его запуска. GuidGen, так же как и UuidGen, умеет генерировать уникальные 128-битовые идентификаторы, но при этом он использует удобный Windows-интерфейс. А идентификаторы понадобятся нам для регистрации сервера и класса CoSay. Для введения новой команды:


  • Дайте команду Tools > External Tools и в окне диалога External Tools нажмите кнопку Add.

  • Введите имя новой команды меню GuidGen, переведите фокус в поле Command и нажмите кнопку справа от нее.

  • С помощью диалога поиска файла, найдите файл Guidgen.exe, который находится в папке .. .\Microsoft Visual Studio.Net\Common7\Tools, и нажмите кнопку Open.

  • Переведите фокус в поле Initial Directory и с помощью кнопки раскрытия выпадающего списка выберите элемент Item Directory.

  • Нажмите OK и теперь с помощью новой команды GuidGen меню Tools вызовите генератор уникальных идентификаторов.

  • Выберите формат DEFINE_GUID и нажмите кнопку Сору, а затем Exit.

  • В окне редактора Studio.Net поместите фокус перед строкой interface ISay и нажмите Ctrl+C. При этом из системного буфера в файл будут помещены три строки кода, которые с точностью до цифр, которые у вас будут другими, имеют такой вид:

    // {170368DO-85BE-43af-AE71-053F506657A2}

    DEFINE_GUID («name»,

    0xl70368d0, 0x85be, 0x43af, 0xae, 0x71, 0x5, Ox3f, 0x50,

    0x66, 0x57, Oxa2);

    Замените аргумент «name» на HD_ISay. Повторите всю процедуру и создайте идентификатор для ко-класса CoSay, который вставьте сразу за идентификатором интерфейса ISay. На сей раз замените аргумент «name» на CLSiD_CoSay, например:

    // {9B865820-2FFA-lld5-98B4-OOE0293F01B2}

    DEFINE_GUID(CLSID_CoSay,

    0х9b865820, 0x2ffa, 0xlldS, 0x98, 0xb4, 0x0, 0xe0, 0x29,

    0x3f, 0xl, 0xb2);

    Сохраните и закройте файл interfaces.h, так как мы больше не будем вносить в него изменений. Если вы хотите знать, что делает макроподстановка DEFINE_GUID, то за ней стоит такое определение:

    #define DEFINE_GUID

    (name, 1, wl, w2, \ b1, b2, bЗ, b4, b5, b6, b7, b8) \ EXTERN_C

    const GUID name \

    = { 1, wl, w2, { b1, b2, bЗ,b4, b5, b6, b7, b8 } }

    Оно означает, что макрос создает структуру с именем <name> типа GUID, которая служит для хранения уникальных идентификаторов СОМ-объектов, интерфейсов, библиотек типов и других реалий причудливого мира СОМ.


    Содержание раздела