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

ОглавлениеДобавить в закладки К обложке

HRESULT Invoke ([in] RPCOLEMESSAGE *pmsg,

[in] IRpcChannelBuffer *pChannel);

// used to support multiple itf types per stub

// используется для поддержки нескольких типов интерфейсов

// для одной заглушки

IRpcStubBuffer *IsIIDSupported([in] REFIID riid);

// used to support multiple itf types per stub

// используется для поддержки нескольких интерфейсов

// для одной заглушки

ULONG CountRefs(vold);

// used by ORPC debugger to find pointer to object

// используется отладчиком ORPC для поиска указателя на объект

HRESULT DebugServerQueryInterface(void **ppv);

// used by ORPC debugger to release pointer to object

// используется отладчиком ORPC для освобождения указателя на объект

void DebugServerRelease(void *pv);

}

Метод Invoke будет вызываться библиотекой СОМ, когда поступит запрос ORPC на объект. При вводе маршалированные [in]-параметры будут находиться в RPCOLEMESSAGE, а при выводе заглушка должна маршалировать HRESULT метода и любые [out]-параметры, которые будут возвращены в блоке ответов ORPC.

Интерфейсный заместитель должен выставлять интерфейс (интерфейсы), за удаленный доступ к которым он отвечает, в дополнение к интерфейсу IRpcProxyBuffer:

[ uuid(D5F56A34-593B-101A-B569-08002B2DBF7A), local, object ]

interface IRpcProxyBuffer : IUnknown {

HRESULT Connect([in] IRpcChannelBuffer *pChannelBuffer);

void Disconnect(void);

}

Интерфейс IRpcPгoxуBuffer должен быть неделегирующим интерфейсом IUnknown интерфейсного заместителя. Все остальные интерфейсы, которые выставляет интерфейсный заместитель, должны делегировать администратору заместителей свои методы IUnknown. Именно в реализациях метода этих других интерфейсов интерфейсный заместитель должен использовать канал для посылки запросов ORPC на метод интерфейсной заглушки Invoke, который затем обрабатывает этот метод в апартаменте объекта.

Интерфейсные заместители и интерфейсные заглушки динамически связываются и совместно используют единый CLSID как для заместителя, так и для заглушки. Такую раздвоенную реализацию часто называют интерфейсным маршалером (interface marshaler). Объект класса интерфейсного маршалера выставляет интерфейс IPSFactoryBuffer:

[ uuid(D5F569DO-593B-101A-B569-08002B2DBF7A), local, object ]

interface IPSFactoryBuffer : IUnknown {

HRESULT CreateProxy(

[in] IUnknown *pUnkOuter,

// ptr to proxy manager

// указатель на администратор заместителей

[in] REFIID riid,

// the requested itf to remote

// запрошенный интерфейс для удаленного доступа

[out] IRpcProxyBuffer **ppProxy,

// ptr. to proxy itf.

// указатель на интерфейс заместителя

[out] void **ppv

// ptr to remoting interface

// указатель на удаленный интерфейс

);

HRESULT CreateStub(

[in] REFIID riid,

// the requested itf to remote

// запрошенный интерфейс для удаленного доступа

[in] IUnknown *pUnkServer,

// ptr to actual object

// указатель на действующий объект

[out] IRpcStubBuffer **ppStub

// ptr to stub on output

// указатель на заглушку на выходе

);

}

Администратор заместителей вызывает метод CreateProxy с целью агрегирования нового интерфейсного заместителя. Администратор заглушек вызывает метод CreateStub с целью создания новой интерфейсной заглушки.

Когда в объекте запрашивается новый интерфейс, то администраторы заместителей и заглушек должны преобразовать запрошенные IID и CLSID интерфейсного маршалера. Под Windows NT 5.0 хранилише класса совершает эти преобразования в директории NT, и они кэшируются в локальном реестре каждой хост-машины. Отображения IID в CLSID всей машины кэшируются в

HKEY_CLASSES_ROOT\Interface

а отображения каждого пользователя кэшируются в

HKEY_CURRENT_USER\Software\Classes\Interface

Один из этих ключей или оба будут содержать подключи для каждого известного интерфейса. Под Windows NT 4.0 и в более ранних версиях не существует хранилища классов и используется только область локального реестра HKEY_CLASSES_ROOT\Interface.

Если в интерфейсе установлен интерфейсный маршалер, то в реестре будет дополнительный подключ (ProxyStubClsid32). который показывает CLSID интерфейсного маршалера. Ниже показаны необходимые ключи реестра для интерфейсного маршалера:


Логин
Пароль
Запомнить меня