Сущность технологии COM



         

Реализация интерфейсных маршалеров


В предыдущем разделе было показано четыре интерфейса, используемых архитектурой стандартного маршалинга. Хотя и допустимо реализовать интерфейсные маршалеры с помощью ручного кодирования на C++, на практике это осуществляется редко. Дело в том, что компилятор IDL может автоматически генерировать исходный С-код для интерфейсного маршалера на основе IDL-определения интерфейса. Созданные MIDL интерфейсные маршалеры преобразуют параметры метода в последовательную форму, используя протокол Сетевого Представления Данных (Network Data Representation — NDR), который допускает демаршалинг этих параметров при различных архитектурах хост-машин. NDR учитывает различия в порядке следования байтов, в формате с плавающей точкой, в наборе символов и в расположении результатов. NDR поддерживает фактически все совместимые с C типы данных. Для того чтобы обеспечить передачу интерфейсных указателей как параметров, MIDL генерирует вызовы CoMarshalInterface / CoUnmarshalInterface для маршалинга любых параметров интерфейсных указателей. Если параметр является статически типизированным интерфейсным указателем:

HRESULT Method([out] IRacer **ppRacer);

то сгенерированный код маршалера будет маршалировать параметр ppRacer путем передачи IID IRacer (IID_IRacer) вызовам CoMarshalInterface / CoUnmarshalInterface. Если же интерфейсный указатель типизирован динамически:

HRESULT Method([in] REFIID riid, [out, iid_is(riid)] void **ppv);

то сгенерированный код маршалера будет маршалировать интерфейс, используя IID, переданный динамически в первый параметр метода.

MIDL генерирует исходный код интерфейсного маршалера для каждого нелокального интерфейса, определенного вне области действия оператора library. В следующем псевдо-IDL коде

// sports.idl // виды спорта. Язык описания интерфейсов [local, object] interface IBoxer : IUnknown { ... } [object] interface IRacer : IUnknown { ... } [object] interface ISwimmer : IUnknown { ... } [helpstring("Sports Lib")] library SportsLibrary { interface IRacer; // include def.


Содержание  Назад  Вперед