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


Настройка маршалинга параметров

Если поведение маршаллинга параметров среды выполнения .NET по умолчанию не делает нужных действий, используйте System.Runtime.InteropServices.MarshalAsAttribute атрибут для настройки маршаллинга параметров. Эти функции настройки не применяются при отключении маршаллинга среды выполнения.

Примечание.

Созданный источником взаимодействие для P/Invokes и COM учитывает только небольшое подмножество MarshalAsAttribute параметров. Вместо этого рекомендуется использовать MarshalUsingAttribute для взаимодействия, созданного источником. Дополнительные сведения см. в разделе "Настраиваемое маршалирование" для создания источника.

Настройка параметров строки

Среда выполнения .NET предусматривает различные форматы для маршалинга строк. Эти методы разбиты на две группы: строки в стиле C и форматы строк, ориентированные на Windows.

Строки в стиле C

Каждый из этих форматов передает строку, которая оканчивается значением NULL, в машинный код. Они различаются кодировкой собственной строки.

Значение System.Runtime.InteropServices.UnmanagedType Кодировка
LPStr ANSI
LPUTF8Str UTF-8
LPWSTR UTF-16
LPTStr UTF-16

Формат UnmanagedType.VBByRefStr немного отличается. Как и LPWStr, он маршалирует строку в собственную строку в стиле C с кодировкой UTF-16. Но управляемая сигнатура требует передавать строку по ссылке, а соответствующая собственная сигнатура принимает строку по значению. Это различие позволяет использовать собственный API, который принимает строку по значению и меняет ее на месте без необходимости использования StringBuilder. Мы не рекомендуем использовать этот формат вручную, так как он может вызывать путаницу из-за несоответствия собственных и управляемых сигнатур.

Форматы строк, ориентированные на Windows

Взаимодействуя с интерфейсами COM или OLE, вы, скорее всего, заметите, что собственные функции принимают строки как аргументы BSTR. Вы можете использовать неуправляемый тип UnmanagedType.BStr, чтобы маршалировать строку как BSTR.

Если вы взаимодействуете с API WinRT, вы можете использовать формат UnmanagedType.HString, чтобы маршалировать строку как HSTRING.

Настройка параметров массива

В среде выполнения .NET можно маршалировать параметры массива несколькими способами. При вызове API, который принимает массив в стиле C, используйте неуправляемый тип UnmanagedType.LPArray. Если для значений в массиве необходимо настроить маршалинг, используйте для этого поле ArraySubType в атрибуте [MarshalAs].

Если вы используете API COM, вам, скорее всего, придется маршалировать свои параметры массивов как SAFEARRAY*. Для этого можно использовать неуправляемый тип UnmanagedType.SafeArray. Тип по умолчанию для элементов SAFEARRAY можно посмотреть в таблице с информацией по настройке полей object. Чтобы настроить точный тип элемента для SAFEARRAY, используйте поля MarshalAsAttribute.SafeArraySubType и MarshalAsAttribute.SafeArrayUserDefinedSubType.

Настройка логических или десятичных параметров

Сведения о маршалинге логических или десятичных параметров см. в разделе "Настройка маршалинга структуры".

Настройка параметров объекта (только для Windows)

В системе Windows среда выполнения .NET предусматривает несколько способов маршалинга параметров объекта в машинный код.

Маршалинг в виде конкретных COM-интерфейсов

Если ваш API принимает указатель на COM-объект, вы можете использовать любой из следующих форматов UnmanagedType с параметром типа object, чтобы среда выполнения .NET выполняла маршалинг в виде этих конкретных интерфейсов:

  • IUnknown
  • IDispatch
  • IInspectable

Кроме того, если тип обозначен как [ComVisible(true)] или маршалируется тип object, можно использовать формат UnmanagedType.Interface, чтобы маршалировать объект как вызываемую оболочку COM для просмотра типа из COM.

Маршалинг в VARIANT

Если ваш собственный API принимает VARIANT Win32, можно использовать формат UnmanagedType.Struct с параметром object для маршалинга объектов в виде VARIANT. Дополнительные сведения о сопоставлении типов NET и VARIANT см. в документации по настройке полей object.

Пользовательские маршаллеры

Если необходимо проецировать собственный COM-интерфейс в другой управляемый тип, используйте формат UnmanagedType.CustomMarshaler и реализацию ICustomMarshaler, чтобы указать свой пользовательский код маршалинга.