На этом шаге мы рассмотрим строение IDL-файла.
IDL-файл формируется компилятором Microsoft IDL (MIDL). MIDL создает в папке проекта следующие файлы:
Созданный мастерами исходный текст представителя/заглушки для объекта Encoder содержится в файлах DllData.c и EncodeServer_p.c. В результате их компиляции создается DLL представителя/заглушки, используемая СОМ для маршалинга данных через границы процессов. Файл библиотеки типов EncodeServer.tlb подключается к DLL в момент сборки компонента.
В проекте EncodeServer используются файл определения GUID (EncodeServer_i.c) и заголовочный файл объявления интерфейса (ЕncodeServer.h). Это нужно знать, потому что эти файлы могут быть вставлены (директивой #include) в код клиента C/C++ для создания и использования экземпляров СОМ-компонента. CLSID-идентификатор CLSID_Encoder и IID-идентификатор IIDIEncoder, объявленные в EncodeServer_i.c, применяются в качестве параметров при вызове CoCreateInstance(). В файле EncodeServer.h объявлен класс, представляющий интерфейс IEncoder, откуда компилятор берет описания методов интерфейса. Экземпляр этого класса используется для вызова методов IEncoder объекта Encoder.
Позже мы научимся использовать эти файлы в клиентских программах.
Вот как выглядит файл EncodeServer.idl:
import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(E24F453C-9B8B-40ED-92A2-BC57594471C9), helpstring("IEncoder Interface"), pointer_default(unique) ] interface IEncoder : IUnknown { [helpstring("method EncodeString")] HRESULT EncodeString([in] const BSTR instring, [out, retval] BSTR * outstring); [propget, helpstring("property Key")] HRESULT Key([out, retval] short *pVal); [propput, helpstring("property Key")] HRESULT Key([in] short newVal); }; [ uuid(EECD8638-CFC3-43F8-A10C-D4C9573E26DD), version(1.0), helpstring("EncodeServer 1.0 Type Library") ] library ENCODESERVERLib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); [ uuid(9DBB482D-4600-43F4-A96E-AEF8F600574E), helpstring("Encoder Class") ] coclass Encoder { [default] interface IEncoder; }; };
В этом IDL-файле определен СОМ-объект (сокласс) Encoder, интерфейс IEncoder и библиотека типов ENCODESERVERLib. Как видно из этого примера, синтаксис IDL очень похож на C++, а самое сильное различие - это заключенные в квадратные скобки атрибуты перед объявлением каждого объекта.
MIDL-атрибуты определяют характеристики интерфейсов, соклассов и библиотек. Например, [uuid] - обязательный атрибут, определяющий уникальный идентификатор (GUID) для каждого из этих объектов. Все идентификаторы GUID в этом файле сгенерированы мастерами ATL. Обратите внимание на атрибуты [propput] и [propget] - они информируют языки типа Visual Basic, что с методом нужно обращаться, как со свойством.
Заметьте, что определение сокласса находится в определении библиотеки типов. Это означает, что описание СОМ-объекта будет включено в библиотеку типов. Объявляя сокласс вне библиотечного блока, Вам удастся избежать включения информации о СОМ-объекте в библиотеку типов. Это весьма полезно при создании СОМ-объектов, используемых только внутренним образом, например лишь другими объектами этой же DLL.
На следующем шаге мы рассмотрим альтернативные способы создания COM-объектов.