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

Двоичный TLB-файл воспринимается клиентом, написанным на одном из COM-совместимых языков. Например, его использует программа просмотра объектов Microsoft Excel. Инструмент студии ClassWizard умеет по информации из библиотеки типов создать классы, которые могут обращаться к свойствам и методам объектов. Программа на Visual Basic осуществляет раннее связывание на основе данных из библиотеки типов. Сведения о библиотеке типов также заносятся в реестр в специальный подраздел TypeLib в разделе HKEY_CLASSES_ROOT.

Новый проект

Для ознакомления с возможностями MIDL создайте новый пустой проект типа Win32 DLL. Для этого:

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

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

3.  Дайте команду Project4Add New Item. В диалоге Add New Item выберите шаблон MIDL File(.idl), задайте имя файла MyComTLib.idl и нажмите кнопку Open;

4.  В окне редактора появится новый документ — заготовка описания COM-объекта на языке MIDL. Введите в него текст, приведенный ниже.

import "oaidl.idl";    // Импорт библиотечных определений

import "ocidl.idl";

[

object, uuid(170368D0-85BE-43af-AE71-053F506657A2),

helpstring("My Test DLL COM-server ISay")

]

interface ISay : IUnknown  //===== Уточненное описание интерфейса ISay

{

HRESULT Say();

HRESULT SetWord([in]BSTR word);

}

[

uuid(0934DA90-608D-4107-9ECC-C7E828AD0928),

version(1.0),

helpstring("My Test DLL COM-server Type Library")

]

library MyCom // Описание библиотеки типов

{

importlib("stdole32.tlb");

[uuid(9B865820-2FFA-11d5-98B4-00E0293F01B2)]

coclass CoSay          // Описание класса реализации интерфейса

{

[default] interface ISay;

};

};

Первый блок кодов, заключенный в квадратные скобки, представляет собой заголовок интерфейса, точнее список его атрибутов. Подобные списки атрибутов вы видите и далее: перед блоком описания библиотеки типов и перед блоком описания ко-класса. Атрибуты заданы ключевыми словами. Ключевое слово object определяет, что данный интерфейс является интерфейсом СОМ. Это означает, что все его методы должны возвращать HRESULT. Атрибут uuid (universally unique identifier) определяет уникальный идентификатор интерфейса, отличая его тем самым от любого другого интерфейса. Атрибут helpstring используется для помещения в библиотеку типов подсказок. Инструментальные среды показывают их на этапе дизайна, некоторые клиенты COM демонстрируют их пользователю.

Важную роль играет атрибут in, который вы видите в параметре функции SetWord. Если параметр помечен как входной, то MIDL знает, что этот параметр нужно передавать только от клиента к компоненту. Этим занимается proxy. Существуют также выходные атрибуты [out] и входо-выходные [in, out]. Выходными параметрами могут быть только указатели. Заглушка типа stub (или заместитель клиента на стороне сервера) должна возвратить выходной параметр. Вот пример, иллюстрирующий использование трех типов атрибутов.

HRESULT TakeAndGive ([in] int x, [in, out] int* y, [out] int* z);

Параметры более сложного типа также могут передавться с помощью механизма proxy-stub. Структуру языка С++ можно определить прямо в файле IDL и использовать ее в качестве параметров методов интерфейса. Например:

struct Point3D { double x, y, z; };

[

object, uuid(32bb8325-b41b-11cf-a6bb-0080c7b2d682), helpstring("Struct"),

pointer_default(unique)

]

interface IPoint : IUnknown

{

HRESULT In ([in]  Point3D pt);

HRESULT Out([out] Point3D* ppt);

};

Постарайтесь вникнуть в смысл конструкций языка, не отвлекаясь на его изучение, так как это потребует заметных усилий и временных затрат. Попробуйте скомпилировать idl-файл. Если на этом этапе возникнут ошибки, то проверьте настройку View4Property Pages4MIDL4General4MkTypeLib Compatible (она должна быть в состоянии No) и дайте команду Rebuild.