интерфейсного заместителя. Администратор заглушек вызывает метод CreateStub с целью создания новой интерфейсной заглушки.
Когда в объекте запрашивается новый интерфейс, то администраторы заместителей и заглушек должны преобразовать запрошенные IID и CLSID интерфейсного маршалера. Под Windows NT 5.0 хранилише класса совершает эти преобразования в директории NT, и они кэшируются в локальном реестре каждой хост-машины. Отображения IID в CLSID всей машины кэшируются в
HKEY_CLASSES_ROOTInterface
а отображения каждого пользователя кэшируются в
HKEY_CURRENT_USERSoftwareClassesInterface
Один из этих ключей или оба будут содержать подключи для каждого известного интерфейса. Под Windows NT 4.0 и в более ранних версиях не существует хранилища классов и используется только область локального реестра HKEY_CLASSES_ROOTInterface.
Если в интерфейсе установлен интерфейсный маршалер, то в реестре будет дополнительный подключ (ProxyStubClsid32). который показывает CLSID интерфейсного маршалера. Ниже показаны необходимые ключи реестра для интерфейсного маршалера:
[HKCRInterface{1A3A29F0-D87E-11d0-8C4F-0080C73925BA}]
@='IRacer'
[HKCRInterface{1A3A29F0-D87E-11d0-8C4F-OB80C73925BA}ProxyStubClsid32]
@='{1A3A29F3-D87E-lld0-8C4F-0080C73925BA}'
Эти элементы реестра означают, что существует внутрипроцессный сервер с CLSID, равным {1A3A29F3-D87E-11d0-8C4F-0080C73925BA}, который реализует интерфейсные заместитель и заглушку для интерфейса IRacer ({1A3A29F0-D87E-11d0-8C4F-0080C73925BA}). Из этого следует, что HKCRCLSID будет иметь подключ для интерфейсного маршалера, отображающего CLSID в соответствующее имя файла DLL. Опять же под Windows NT 5.0 это отображение может содержаться в хранилище классов, которое способно динамически заполнять локальный реестр. Поскольку интерфейсный маршалер должен выполняться в том же апартаменте, что и администратор заместителей или администратор заглушек, они должны использовать (флаг) ThreadingModel="Both' для гарантии того, что они всегда могут загрузиться в нужный апартамент.
Реализация интерфейсных маршалеров
В предыдущем разделе было показано четыре интерфейса, используемых архитектурой стандартного маршалинга. Хотя и допустимо реализовать интерфейсные маршалеры с помощью ручного кодирования на C++, на практике это осуществляется редко. Дело в том, что компилятор IDL может автоматически генерировать исходный С-код для интерфейсного маршалера на основе IDL-определения интерфейса. Созданные MIDL интерфейсные маршалеры преобразуют параметры метода в последовательную форму, используя протокол Сетевого Представления Данных (
HRESULT Method([out] IRacer **ppRacer);
то сгенерированный код маршалера будет маршалировать параметр
HRESULT Method([in] REFIID riid, [out, iid_is(riid)] void **ppv);
то сгенерированный код маршалера будет маршалировать интерфейс, используя
MIDL генерирует исходный код интерфейсного маршалера для каждого нелокального интерфейса, определенного
// sports.idl
// виды спорта. Язык описания интерфейсов
[local, object] interface IBoxer : IUnknown { … }
[object] interface IRacer : IUnknown { … }
[object] interface ISwimmer : IUnknown { … }
[helpstring(«Sports Lib»)]
library SportsLibrary {
interface IRacer;
// include def. of IRacer in TLB
// включаем определение IRacer в библиотеку типов TLB
[object] interface IWrestler : IUnknown { … } }
только интерфейсы
Если MIDL представлен в IDL такого типа, он будет генерировать пять файлов. Файл
Для того чтобы построить интерфейсный маршалер из этих сгенерированных файлов, необходимо