Маршалинг взаимодействия

Маршалирование взаимодействия управляет передачей данных в аргументах метода и возвращаемых значений между управляемой и неуправляемой памятью во время вызовов. Маршалирование взаимодействия — это действие во время выполнения, выполняемое службой маршалинга среды CLR.

Представление большинства типов данных является общим как в управляемой, так и в неуправляемой памяти. Маршализатор взаимодействия обрабатывает эти типы за вас. Другие типы могут иметь неоднозначное представление или могут вообще не быть представленными в управляемой памяти.

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

Вызов неуправляемого кода и модели взаимодействия COM

Среда CLR предоставляет два механизма взаимодействия с неуправляемым кодом.

  • Вызов неуправляемого кода, позволяющий управляемому коду вызывать функции, экспортированные из неуправляемой библиотеки.
  • COM-взаимодействие, позволяющее управляемому коду взаимодействовать с COM-объектами с помощью интерфейсов.

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

Вызов

На самом низком уровне оба механизма используют одну и ту же службу маршалинга взаимодействия; однако некоторые типы данных поддерживаются исключительно COM-взаимодействием или вызовом платформы. Дополнительные сведения см. в разделе Поведение маршалинга по умолчанию.

Маршалинг и COM-квартиры

Маршализатор взаимодействия маршалирует данные между кучей среды CLR и неуправляемой кучей. Маршалирование происходит всякий раз, когда вызывающий и вызываемый не могут работать с одинаковым экземпляром данных. Маршализатор взаимодействия позволяет вызывающему и вызывающему абоненту работать с теми же данными, даже если у них есть собственная копия данных.

В COM также есть маршализатор, который маршалирует данные между com-квартирами или различными процессами COM. При вызове управляемого и неуправляемого кода в одном и том же com-объекте маршализатор взаимодействия является единственным задействованным маршализатором. При вызове управляемого кода и неуправляемого кода в другом com-объекте или другом процессе используются маршализатор взаимодействия и маршализатор COM.

Клиенты COM и управляемые серверы

Для экспортированного управляемого сервера с библиотекой типов, зарегистрированной с помощью средства регистрации сборок (Regasm.exe), существует запись реестра ThreadingModel со значением Both. Это значение показывает, что данный сервер можно активировать как в однопотоковом подразделении (STA), так и в многопотоковом подразделении (MTA). Как показано в таблице ниже, серверный объект создается в том же подразделении, что и вызывающий объект.

Клиент COM Сервер .NET Требования маршалинга
STA Both становится STA. Маршалинг в одноквартирном режиме.
MTA Both становится MTA. Маршалинг в одноквартирном режиме.

Так как клиент и сервер находятся в одной квартире, служба маршалинга взаимодействия автоматически обрабатывает все данные. На следующем рисунке показана служба маршалинга взаимодействия, работающая между управляемыми и неуправляемыми кучами в одном и том же объекте в стиле COM.

Маршалирование взаимодействия между управляемыми и неуправляемыми кучами

Если планируется экспортировать управляемый сервер, учтите, что клиент COM определяет подразделение сервера. Управляемый сервер, вызванный клиентом COM, инициализированным в многопотоковом подразделении, должен обеспечить потокобезопасность.

Управляемые клиенты и COM-серверы

По умолчанию для управляемого клиента используется многопотоковое подразделение, однако тип приложения клиента .NET может изменить эту настройку. Например, для клиента Visual Basic настроено однопотоковое подразделение. Для проверки и изменения настройки подразделения для управляемого клиента можно использовать атрибут System.STAThreadAttribute, атрибут System.MTAThreadAttribute, свойство Thread.ApartmentState или свойство Page.AspCompatMode.

Автор компонента настраивает сходство потоков COM-сервера. В таблице ниже показаны сочетания параметров подразделения для клиентов .NET и COM-серверов. Здесь также показаны результирующие требования к маршалингу для комбинаций.

Клиент .NET COM-сервер Требования маршалинга
MTA (по умолчанию) MTA

STA
Маршалирование взаимодействия.

Взаимодействие и маршалинг COM.
STA MTA

STA
Взаимодействие и маршалинг COM.

Маршалирование взаимодействия.

Когда управляемый клиент и неуправляемый сервер находятся в одном объекте, служба маршалинга взаимодействия обрабатывает все данные. Однако при инициализации клиента и сервера в разных квартирах также требуется маршалирование COM. На следующем рисунке показаны элементы вызова между подразделениями.

Вызов между клиентом .NET и COM-объектом, находящимися в разных подразделениях

Для маршалинга между квартирами можно сделать следующее:

  • Примите накладные расходы на маршалинг между квартирами, что заметно только при наличии большого количества вызовов через границу. Чтобы вызовы успешно пересекали границу подразделения, необходимо зарегистрировать библиотеку типов COM-компонента.

  • Изменить основной поток, выбрав для клиентского потока однопотоковое или многопотоковое подразделение. Например, если клиент C# вызывает множество COM-компонентов STA, можно избежать маршалинга между подразделениями, задав потоку main значение STA.

    Примечание

    После установки для потока клиента C# значения STA вызовы com-компонентов MTA потребуют маршалинга между подразделениями.

Инструкции по выбору модели подразделения в явном виде см. в разделе Управляемые и неуправляемые потоки.

Маршалинг удаленных вызовов

Как и в случае с маршалингом между подразделениями, маршалирование COM участвует в каждом вызове управляемого и неуправляемого кода, когда объекты находятся в отдельных процессах. Пример:

  • Клиент COM, обращающийся к управляемому серверу на удаленном компьютере, использует DCOM.
  • Управляемый клиент, обращающийся к СОМ-серверу на удаленном компьютере, использует DCOM.

На следующем рисунке показано, как маршалинг взаимодействия и маршалирование COM обеспечивают каналы связи между процессами и узлами.

Маршалирование между процессами

Сохранение идентификаторов

Среда CLR сохраняет идентификаторы управляемых и неуправляемых ссылок. На схеме ниже показан поток прямых неуправляемых ссылок (верхняя строка) и прямых управляемых ссылок (нижняя строка) через границы между процессами и узлами.

на вызываемую оболочку COM и вызываемую оболочку среды выполненияСсылка

На этой схеме:

  • Неуправляемый клиент получает ссылку на COM-объект от управляемого объекта, получившего эту ссылку от удаленного узла. Механизмом удаленного взаимодействия является DCOM.

  • Управляемый клиент получает ссылку на управляемый объект от COM-объекта, получившего эту ссылку от удаленного узла. Механизмом удаленного взаимодействия является DCOM.

    Примечание

    Экспортированная библиотека типов управляемого сервера должна быть зарегистрирована.

Число границ процессов между вызывающим и вызываемым объектами несущественно; одни и те же прямые ссылки используются для вызовов, входящих в процессы и исходящих из них.

Управляемое удаленное взаимодействие

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

Удаленные вызовы SOAP или TcpChannel Удаленные вызовы через брандмауэры с помощью протокола SOAP или класса TcpChannel

Некоторые неуправляемые вызовы, например вызовы между обслуживаемыми COM-компонентами, могут проводиться через SOAP.

Заголовок Описание
Поведение маршалинга по умолчанию Описывает правила, которые служба маршалинга взаимодействия использует для маршалинга данных.
Маршалинг данных с помощью вызова платформы Описывается способ объявления параметров метода и передачи аргументов в функции, экспортируемые неуправляемыми библиотеками.
Маршалинг данных с помощью COM-взаимодействия Описывает, как настроить com-оболочки для изменения поведения маршалинга.
Практическое руководство. Миграция DCOM с управляемым кодом в WCF Описывается переход с модели DCOM на WCF.
Практическое руководство. Сопоставление значений HRESULT и исключений Описывается, как сопоставить настраиваемые исключения со значениями HRESULT, и приводится полный перечень сопоставлений значений HRESULT с соответствующими классами исключений платформы .NET Framework.
Взаимодействие с помощью универсальных типов Описываются действия, поддерживаемые при использовании универсальных типов для взаимодействия COM.
Взаимодействие с неуправляемым кодом Описываются службы взаимодействия, предоставляемые средой CLR.
Расширенное COM-взаимодействие Приводятся ссылки на дополнительные сведения о включении COM-компонентов в разрабатываемое приложение .NET Framework.
Вопросы разработки для взаимодействия Приводятся советы по написанию кода встроенных COM-компонентов.

Справочник

System.Runtime.InteropServices