Настройка маршалинга параметров
Если поведение маршаллинга параметров среды выполнения .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, чтобы указать свой пользовательский код маршалинга.