Поделиться через


Метод IMarshal::MarshalInterface (objidl.h)

Маршалирует указатель интерфейса.

Синтаксис

HRESULT MarshalInterface(
  [in] IStream *pStm,
  [in] REFIID  riid,
  [in] void    *pv,
  [in] DWORD   dwDestContext,
  [in] void    *pvDestContext,
  [in] DWORD   mshlflags
);

Параметры

[in] pStm

Указатель на поток, используемый во время маршалинга.

[in] riid

Ссылка на идентификатор маршалированного интерфейса. Этот интерфейс должен быть производным от интерфейса IUnknown .

[in] pv

Указатель на указатель интерфейса для маршалирования. Этот параметр может иметь значение NULL , если вызывающий объект не имеет указателя на нужный интерфейс.

[in] dwDestContext

Контекст назначения, в котором требуется отменить удаление указанного интерфейса. Возможные значения для dwDestContext поступают из перечисления MSHCTX. В настоящее время размежевание может происходить либо в другом объекте текущего процесса (MSHCTX_INPROC), либо в другом процессе на том же компьютере, что и текущий процесс (MSHCTX_LOCAL).

[in] pvDestContext

Этот параметр зарезервирован и должен иметь значение 0.

[in] mshlflags

Указывает, должны ли маршалированные данные передаваться обратно в клиентский процесс (в типичном случае) или записываться в глобальную таблицу, где их могут получить несколько клиентов. Возможные значения поступают из перечисления MSHLFLAGS .

Возвращаемое значение

Этот метод может возвращать стандартное возвращаемое значение E_FAIL, а также следующие значения.

Код возврата Описание
S_OK
Указатель интерфейса успешно маршалирован.
E_NOINTERFACE
Указанный интерфейс не поддерживается.
STG_E_MEDIUMFULL
Поток заполнен.

Комментарии

Этот метод вызывается косвенно при вызове CoMarshalInterface любым кодом в серверном процессе, ответственным за маршалинг указателя на интерфейс объекта . Этот код маршалинга обычно представляет собой заглушку, созданную COM для одного из нескольких интерфейсов, которые могут маршалировать указатель на интерфейс, реализованный в совершенно другом объекте. Примерами являются интерфейсы IClassFactory и IOleItemContainer . В целях обсуждения код, отвечающий за маршалинг указателя, называется заглушка маршалинга.

Примечания к вызывающим абонентам

Как правило, вместо вызова MarshalInterface напрямую заглушка маршалинга должна вызывать функцию CoMarshalInterface , которая содержит вызов этого метода. Заглушка вызывает этот вызов для команды объекта для записи его маршалинга данных в поток. Затем заглушка передает данные маршалинга обратно в клиентский процесс или записывает их в глобальную таблицу, где их могут отменить несколько клиентов. Вызову заглушки к CoMarshalInterface обычно предшествует вызов CoGetMarshalSizeMax , чтобы получить максимальный размер буфера потока, в который будут записываться данные маршалинга.

Этот метод не вызывается явным образом, если вы реализуете существующие COM-интерфейсы или определяете собственные интерфейсы с помощью языка определения интерфейса Майкрософт (MIDL). В любом случае заглушка, созданная MIDL, автоматически выполняет вызов.

Если вы не используете MIDL для определения собственного интерфейса, заглушка маршалинга должна вызывать этот метод напрямую или косвенно. Реализация заглушки должна вызывать MarshalInterface сразу после предыдущего вызова метода IMarshal::GetMarshalSizeMax . Так как значение, возвращаемое Методом GetMarshalSizeMax , гарантированно будет действительным только при условии, что внутреннее состояние маршалируемого объекта не изменится, задержка вызова MarshalInterface сопряжена с риском того, что объекту потребуется больше буфера потока, чем изначально было указано.

Если вызывающий объект имеет указатель на интерфейс для маршалирования, он должен, с точки зрения эффективности, использовать параметр pv для передачи этого указателя. Таким образом, реализация, которая может использовать такой указатель для определения соответствующего идентификатора CLSID для прокси-сервера, не требует вызова QueryInterface для себя. Если вызывающий объект не имеет указателя на интерфейс для маршалирования, он может передать значение NULL.

Примечания для разработчиков

Реализация MarshalInterface должна записывать в поток все данные, необходимые для инициализации прокси-сервера на принимающей стороне. Такие данные будут содержать ссылку на интерфейс для маршалирования, значение MSHLFLAGS , указывающее, должны ли данные возвращаться в клиентский процесс или записываться в глобальную таблицу, а также все необходимое для подключения к объекту, например именованный канал, дескриптор окна или указатель на канал RPC.

Реализация не должна предполагать, что поток достаточно велик для хранения всех данных. Скорее, он должен корректно обрабатывать ошибку STG_E_MEDIUMFULL. Непосредственно перед выходом реализация должна разместить указатель поиска в потоке сразу после последнего байта записанных данных.

Если параметр pv имеет значение NULL и для реализации требуется указатель интерфейса, он может вызвать QueryInterface для текущего объекта, чтобы получить его. Параметр pv существует только для повышения эффективности.

Чтобы обеспечить правильную работу реализации MarshalInterface при поддержке новых контекстов назначения в будущем, делегируйте маршалинг в реализацию COM по умолчанию для всех значений dwDestContext , которые не обрабатываются реализацией. Чтобы делегировать маршалинг реализации com по умолчанию, вызовите вспомогающую функцию CoGetStandardMarshal .

С помощью перечисления MSHLFLAGS вызывающие элементы могут указать, должен ли указатель интерфейса маршалироваться обратно в один клиент или записываться в глобальную таблицу, где он может быть разархивирован несколькими клиентами. Необходимо убедиться, что объект может обрабатывать вызовы от нескольких прокси-серверов, которые могут быть созданы из одних и того же данных инициализации.

Требования

   
Минимальная версия клиента Windows 2000 Профессиональная [классические приложения | Приложения UWP]
Минимальная версия сервера Windows 2000 Server [классические приложения | Приложения UWP]
Целевая платформа Windows
Header objidl.h (включая ObjIdl.h)

См. также раздел

CoMarshalInterface

IMarshal