Поделиться через


Анатомия файла 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 напрямую или косвенно.

Параметр в направлении указывает параметр, заданный только вызывающим параметром. Параметр out указывает данные, передаваемые обратно вызывающей стороне. Использование обоих атрибутов направления для одного параметра указывает, что параметр используется как для отправки данных в метод, так и для передачи данных обратно вызывающей стороне.

Атрибут pointer_default указывает тип указателя по умолчанию (unique, 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, helpstring и version.

В определении библиотеки типов директива importlib добавляет в скомпилированную библиотеку типов. Все определения библиотеки типов должны содержать библиотеку базовых типов, определенную в Stdole32.tlb.

Это определение библиотеки типов демонстрирует три различных способа включения интерфейсов в библиотеку типов. IFace3 включается только путем ссылки на него в инструкции библиотеки.

Оператор coclass определяет совершенно новый класс компонентов BkfstComponent, который включает два ранее определенных интерфейса, IFace1 и IFace2. Атрибут по умолчанию назначает IFace1 интерфейсом по умолчанию.

IFace4 описан в инструкции библиотеки. Атрибутpropput в MethodD указывает, что метод выполняет действие set для свойства того же имени. Атрибут propget указывает, что метод извлекает сведения из свойства того же имени, что и метод. Атрибут retval в MethodD обозначает выходной параметр, содержащий возвращаемое значение функции.