Анатомия файла IDL
В этих примерах файлы IDL демонстрируют основные конструкции определения интерфейса. Выделение памяти, пользовательское маршалинг и асинхронное обмен сообщениями являются лишь несколькими функциями, которые можно реализовать в пользовательском com-интерфейсе. Атрибуты MIDL используются для определения com-интерфейсов. Дополнительные сведения о реализации интерфейсов и библиотек типов, включая сводку атрибутов MIDL, см. в определения интерфейсов и библиотек типов в руководстве и справочнике программиста MIDL. Полный справочник по всем атрибутам MIDL, ключевым словам и директивам см. в справочнике по языку MIDL.
Example.idl
В следующем примере IDL-файл определяет два COM-интерфейса. В этом файле IDL Midl.exe создаст файлы прокси-сервера или заглушки и маршалинг кода и заголовка. Диссекция строки следует примеру.
//
// Example.idl
//
import "mydefs.h","unknwn.idl";
[
object,
uuid(a03d1420-b1ec-11d0-8c3a-00c04fc31d2f),
] interface IFace1 : IUnknown
{
HRESULT MethodA([in] short Bread, [out] BKFST * pBToast);
HRESULT MethodB([in, out] BKFST * pBPoptart);
};
[
object,
uuid(a03d1421-b1ec-11d0-8c3a-00c04fc31d2f),
pointer_default(unique)
] interface IFace2 : IUnknown
{
HRESULT MethodC([in] long Max,
[in, max_is(Max)] BkfstStuff[ ],
[out] long * pSize,
[out, size_is( , *pSize)] BKFST ** ppBKFST);
};
Оператор импортаIDLиспользуется здесь для ввода в файл заголовка Mydefs.h, который содержит определяемые пользователем типы и Unknwn.idl, который содержит определение IUnknown, от которого наследуется IFace1 и IFace2.
Атрибут объекта определяет интерфейс как интерфейс объекта и сообщает компилятору MIDL создавать код прокси-сервера или заглушки вместо заглушки клиента и сервера RPC. Методы интерфейса объектов должны иметь тип возвращаемого значения HRESULT, чтобы разрешить базовому механизму RPC сообщать об ошибках для вызовов, которые не завершаются из-за проблем с сетью.
Атрибут uuid указывает идентификатор интерфейса (IID). Каждый интерфейс, класс и библиотека типов должны быть идентифицированы с собственным уникальным идентификатором. Используйте программу Uuidgen.exe для создания набора уникальных идентификаторов для интерфейсов и других компонентов.
Ключевое словоинтерфейсаопределяет имя интерфейса. Все интерфейсы объектов должны быть производными от IUnknown.
в параметре направления указывает параметр, заданный только вызывающим параметром. Параметр указывает данные, передаваемые обратно вызывающей стороне. Использование обоих атрибутов направления для одного параметра указывает, что параметр используется как для отправки данных в метод, так и для передачи данных обратно вызывающей стороне.
Атрибут pointer_default указывает тип указателя по умолчанию (уникальные, refили ptr) для всех указателей, за исключением тех, которые включены в списки параметров. Если тип по умолчанию не указан, MIDL предполагает, что одиночные указатели уникальные. Однако при наличии нескольких уровней указателей необходимо явно указать тип указателя по умолчанию, даже если тип по умолчанию должен быть уникальным.
В предыдущем примере массив BkfstStuff[ ] — это соответствующий массив, размер которого определяется во время выполнения. Атрибут max_is указывает переменную, содержащую максимальное значение индекса массива.
Атрибут size_is также используется для указания размера массива или, как в предыдущем примере, нескольких уровней указателей. В этом примере вызов можно выполнить, не зная заранее, сколько данных будет возвращено.
Example2.idl
В следующем примере IDL (который повторно использует интерфейсы, описанные в предыдущем примере IDL), показаны различные способы создания сведений о библиотеке типов для интерфейсов.
//
// Example2.idl
//
import "example.idl","oaidl.idl";
[
uuid(a03d1422-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("IFace3 interface"),
pointer_default(unique);
dual,
oleautomation
]
interface IFace3 : IDispatch
{
HRESULT MethodD([in] BSTR OrderIn,
[out, retval] * pTakeOut);
}; //end IFace3 def
[
uuid(a03d1423-b1ec-11d0-8c3a-00c04fc31d2f),
version(1.0),
helpstring("Example Type Library"),
] library ExampleLib
{
importlib("stdole32.tlb");
interface IFace3;
[
uuid(a03d1424-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("Breakfast Component Class")
] coclass BkfstComponent
{
[default]interface IFace1;
interfaceIFace2
}; //end coclass def
[
uuid(a03d1424-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("IFace4 interface"),
pointer_default(unique);
dual,
oleautomation
]
interface IFace4 : IDispatch
{
[propput] HRESULT MethodD([in] BSTR OrderIn);
[propget] HRESULT MethodE([out, retval] * pTakeOut);
}; //end IFace4 def
}; //end library def
Вспомогательный атрибутявляется необязательным; вы используете его для краткого описания объекта или предоставления строки состояния. Эти строки справки доступны для чтения с помощью браузера объектов, например браузера, предоставленного в Microsoft Visual Basic.
Атрибут двойной в IFace3 создает интерфейс, который является интерфейсом отправки и com-интерфейсом. Поскольку он является производным от IDispatch, двойной интерфейс поддерживает автоматизацию, то есть то, что указывает атрибут oleautomation. IFace3 импортирует Oaidl.idl, чтобы получить определение IDispatch.
Инструкциябиблиотекиопределяет библиотеку типов ExampleLib, которая имеет собственные uuid, вспомогательныеи атрибуты версии.
В определении библиотеки типов директива importlib импорта добавляется в скомпилированную библиотеку типов. Все определения библиотеки типов должны содержать библиотеку базовых типов, определенную в Stdole32.tlb.
Это определение библиотеки типов демонстрирует три различных способа включения интерфейсов в библиотеку типов. IFace3 включается только путем ссылки на него в инструкции библиотеки.
Оператор coclass определяет совершенно новый класс компонентов BkfstComponent, включающий два ранее определенных интерфейса, IFace1 и IFace2. Атрибут по умолчанию назначает IFace1 интерфейсом по умолчанию.
IFace4 описан в инструкции библиотеки. Атрибут propput в MethodD указывает, что метод выполняет действие set для свойства того же имени. Атрибут propget указывает, что метод извлекает сведения из свойства того же имени, что и метод. Атрибут retval в MethodD обозначает выходной параметр, содержащий возвращаемое значение функции.