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

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

Когда CoUnmarshalInterface демаршалирует стандартно маршалированную объектную ссылку, фактически эта функция возвращает указатель администратору заместителей (proxy manager). Этот администратор заместителей действует как копия объекта со стороны клиента и, подобно администратору заглушек, не имеет никакой априорной информации ни об одним из интерфейсов СОМ. Однако администратор заместителей знает, как реализовать три метода IUnknown. Любые дополнительные вызовы AddRef или Release просто увеличивают или уменьшают на единицу внутренний счетчик ссылок в администраторе заместителей и никогда не передаются с использованием ORPC. Последний Release в администраторе заместителей уничтожает заместитель, посылая в апартамент объекта требование о прекращении связи. Запросы QueryInterface в администраторе заместителей обрабатываются несколько иначе. Подобно администратору заглушек, администратор заместителей не имеет никакой априорной информации об интерфейсах СОМ. Вместо этого администратор заместителей должен загружать интерфейсные заместители, выставляющие тот интерфейс, на который в данный момент идет запрос. Интерфейсный заместитель преобразует вызовы метода в запросы ORPC. В отличие от администратора заглушек, администратор заместителей является непосредственно видимым для программистов, и для обеспечения правильных отношений идентификации интерфейсные заместители агрегируются в идентификационную единицу администратора заместителей. Это создает у клиента иллюзию, что все интерфейсы выставляются одним СОМ-объектом. На рис. 5.4 показаны отношения между администратором заместителей, интерфейсными заместителями и заглушкой.

Как показано на рис. 5.4, заместитель связывается с заглушкой через третий объект, называемый каналом. Канал – это поддерживаемая СОМ обертка вокруг слоя RPC на этапе выполнения. Канал выставляет интерфейс IRpcChannelBuffer

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

interface IRpcChannelBuffer : IUnknown {

// programmatic representation of ORPC message

// программное представление сообщения ORPC

typedef struct tagRPCOLEMESSAGE {

void *reserved1;

unsigned long dataRepresentation;

// endian/ebcdic

// endian /расширенный двоично-десятичный код

// для обмена информацией

void *Buffer;

// payload goes here

// полезная нагрузка идет сюда

ULONG cbBuffer;

// length of payload

// длина полезной нагрузки

ULONG iMethod;

// which method?

// чей метод?

void *reserved2[5];

ULONG rpcFlags;

} RPCOLEMESSAGE;

// allocate a transmission buffer

// выделяем буфер для передачи

HRESULT GetBuffer([inl RPCOLEMESSAGE *pMessage,

[in] REFIID riid);

// send an ORPC request and receive an ORPC response

// посылаем ORPC-запрос и получаем ORPC-ответ

HRESULT SendReceive([in,out] RPCOLEMESSAGE *pMessage,

[out] ULONG *pStatus);

// deallocate a transmission buffer

// освобождаем буфер передачи

HRESULT FreeBuffer([in] RPCOLEMESSAGE *pMessage);

// get distance to destination for CoMarshalInterface

// получаем расстояние до адресата для CoMarshalInterface

HRESULT GetDestCtx([out] DWORD *pdwDestCtx,

[out] void **ppvDestCtx);

// check for explicit disconnects

// проверяем явные отсоединения

HRESULT IsConnected(void);

}

Интерфейсные заместители используют метод SendReceive этого интерфейса, чтобы заставить канал послать блок запросов ORPC и получить блок ответов ORPC.

Интерфейсные заместители и заглушки являются обычными внутрипроцессными объектами СОМ, которые создаются администраторами соответственно заместителей и заглушек с использованием обычной СОМ-технологии активизации. Интерфейсная заглушка должна выставить интерфейс IRpcStubBuffer:

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

interface IRpcStubBuffer : IUnknown {

// called to connect stub to object

// вызван для соединения заглушки с объектом

HRESULT Connect([in] IUnknown *pUnkServer),

// called to inform stub to release object

// вызван для информирования заглушки об освобождении объекта

void Disconnect(void);

// called when ORPC request arrives

// вызывается, когда поступает запрос ORPC


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