Атрибуты направления
Каждый параметр метода может быть связан с атрибутом InAttribute, атрибутом OutAttribute или обоими атрибутами. Атрибуты направления применяются в режиме разработки для изменения маршалинга между управляемой и неуправляемой памятью во время выполнения.
Атрибуты InAttribute и OutAttribute находятся в пространстве имен System.Runtime.InteropServices и эквивалентны атрибутам интерфейса Interface Definition Language (IDL) [in], [out], [in/out] и [out, retval].
![]() |
---|
Возвращаемое значение сигнатуры управляемого метода всегда отображается в [out, retval] в библиотеке типов.Возможный эквивалентный атрибут направления отсутствует. |
Атрибуты направления необязательны. Их применяют к параметрам метода, когда нужно изменить стандартное поведение упаковщика. Если в параметре метода атрибуты направления не используются, упаковщик определяет направление потока на основании типа параметра ((значение или ссылка) и соответствующих модификаторов, если они заданы.
В некоторых языках присутствуют зарезервированные слова, позволяющие изменять направление потока параметров метода. В следующей таблице приведен список зарезервированных слов, связанных с направлением, предоставляемых Visual Basic 2005 и C#, а также показан эквивалентный атрибут интерфейса IDL.
Visual Basic 2005 |
C# |
Атрибут IDL |
---|---|---|
ByVal |
Эквивалента нет. |
[in] |
ByRef |
ref |
[in/out] |
Эквивалента нет. |
out |
[out] |
Модификаторы параметра ByRef, ref и out обеспечивают маршалинг аргументов метода по ссылке, а не по значению. Аргументы метода, передаваемые по значению, маршалируются в неуправляемый код как значения в стеке; аргументы, передаваемые по ссылке, маршалируются как указатели в стеке. На следующем рисунке показано поведение маршалинга по умолчанию для типов значений и ссылочных типов с модификаторами параметров.
Маршалинг по умолчанию при передаче аргументов метода в неуправляемый код
По соображениям, связанным с производительностью, ссылочные типы (классы, массивы, строки и интерфейсы) передаваемые по значению, по умолчанию маршалируются как параметры In. Изменения этих типов не видны, пока к параметру метода не применяются атрибуты InAttribute и OutAttribute (или только OutAttribute). Класс StringBuilder, являющийся исключением из правила, маршалируется как параметр In/Out.
Упаковщик взаимодействия гарантирует следующее поведение, связанное с атрибутами направления:
Упаковщик взаимодействия никогда не создает операции записи в параметр In, переданный из неуправляемого кода. Таким образом, неуправляемый код может безопасно передавать указатель на страницу только для чтения или указатель на данные, открытые для параллельного доступа.
Когда копируемый объект содержит объект, для которого выделена память, такой как BSTR, упаковщик всегда выполняет правильную последовательность выделений и уничтожений, определяемую параметрами In/Out.
Очень важно правильно применять атрибуты направления в разрабатываемом коде. Правильное применение атрибутов InAttribute иOutAttribute к параметрам в управляемом коде гарантирует, что программа экспорта библиотеки типов (Tlbexp.exe) использует эти биты для установки битов In/Out в соответствующей библиотеке типов. Это особенно важно для ссылочных типов, которые могут закрепляться, таких как некоторые массивы и классы.
См. также
Основные понятия
Управление памятью с помощью упаковщика взаимодействия
Преобразуемые и непреобразуемые типы