Сущность технологии СОМ. Библиотека программиста | страница 48




// calculator.h – generated by MIDL

// calculator.h – генерированный MIDL

// bring in def. of IUnknown

// вводим определения IUnknown

#include «unknwn.h»

extern "C" const IID IID_ICalculator;

interface ICalculator : public IUnknown

{

virtual HRESULT STDMETHODCALLTYPE Clear(void) = 0;

virtual HRESULT STDMETHODCALLTYPE Add(long n) = 0;

virtual HRESULT STDMETHODCALLTYPE Sum(long *pn) = 0;

}


Компилятор MIDL также создаст С-файл, содержащий фактические определения всех GUID, имеющихся в исходном IDL-файле:


// calculator_i.с – generated by MIDL

const IID IID_ICalculator =

{ 0xBDA4A270, 0xA1BA, 0x11d0, { 0x8C, 0x2C, 

0x00, 0х80, 0хC7, 0х39, 0x25, 0xBA } };

Каждый проект, который будет использовать этот интерфейс, должен или добавить calculator_i.c к своему файлу сборки (makefile), или включить calculator_i.c в один из исходных файлов на С или C++ с использованием препроцессора С. Если это не сделано, то идентификатору IID_ICalculator не будет выделено памяти для его 128-битного значения и проект не будет скомпонован по причине неразрешенных внешних идентификаторов.

СОМ не накладывает никаких ограничений на глубину иерархии интерфейсов при условии, что конечным базовым интерфейсом является IUnknown. Нижеследующий IDL является вполне допустимым и корректным для СОМ:


import «unknwn.idl»;

[object, uuid(DF12E151-A29A-11d0-8C2D-0080C73925BA)]

interface IAnimal : IUnknown {

HRESULT Eat(void);

}

[object, uuid(DF12E152-A29A-11d0-8C2D-0080C73925BA)]

interface ICat : IAnimal

{

HRESULT IgnoreMaster(void);

}

[object, uuid(DF12E153-A29A-11d0-8C2D-0080C73925BA)]

interface IDog : IAnimal

{

HRESULT Bark(void);

}

[object, uuid(DF12E154-A29A-11d0-8C2D-0080C73925BA)]

interface IPug : IDog

{

HRESULT Snore(void);

}

[object, uuid(DF12E155-A29A-11d0-8C2D-0080C73925BA)]

interface IOldPug : IPug

{

HRESULT SnoreLoudly(void);

}


СОМ накладывает одно ограничение на наследование интерфейсов: интерфейсы СОМ не могут быть прямыми потомками более чем одного интерфейса. Следующий фрагмент в СОМ недопустим:


[object, uuid(DF12E156-A29A-11d0-8C2D-0080C73925BA)]

interface ICatDog : ICat, IDog

{

// illegal, multiple bases

// неверно, несколько базовых интерфейсов

HRESULT Meowbark(void);

}


СОМ запрещает наследование от нескольких интерфейсов по целому ряду причин. Одна из них состоит в том, что двоичное представление результирующего абстрактного базового класса C++ не будет независимым от компилятора. В этом случае СОМ уже не будет являться двоичным стандартом, независимым от разработчика. Другая причина кроется в тесной связи между СОМ и DCE RPC. При ограничении наследования интерфейсов одним базовым интерфейсом преобразование между интерфейсами СОМ и интерфейсными векторами DCE RPC вполне однозначно. В конце концов, отсутствие поддержки нескольких базовых интерфейсов не является ограничением, так как каждая реализация может выбрать для открытия столько интерфейсов, сколько пожелает. Это означает, что основанный на СОМ Cat/Dog по-прежнему допустим на уровне