Учебник по 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, которая служит для хранения уникальных идентификаторов СОМ-объектов, интерфейсов, библиотек типов и других реалий причудливого мира СОМ.


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