Маршалинг по умолчанию для массивовDefault Marshaling for Arrays

Если приложение полностью состоит из управляемого кода, общеязыковая среда выполнения (CLR) передает типы массивов в качестве параметров ввода-вывода.In an application consisting entirely of managed code, the common language runtime passes array types as In/Out parameters. В отличие от этого, маршалер взаимодействия по умолчанию передает массив в качестве параметров ввода.In contrast, the interop marshaler passes an array as In parameters by default.

В рамках оптимизации закрепления непреобразуемый массив может выступать в качестве параметра ввода-вывода при взаимодействии с объектами в том же подразделении.With pinning optimization, a blittable array can appear to operate as an In/Out parameter when interacting with objects in the same apartment. Тем не менее при последующем экспорте кода в библиотеку типов, используемую для создания учетной записи посредника между компьютерами, если эта библиотека используется для маршалинга вызовов между подразделениями, вызовы могут получать фактические характеристики параметра ввода.However, if you later export the code to a type library used to generate the cross-machine proxy, and that library is used to marshal your calls across apartments, the calls can revert to true In parameter behavior.

Массивы имеют сложную структуру, поэтому для проведения различий между управляемыми и неуправляемыми массивами требуется больше информации, чем для других преобразуемых типов.Arrays are complex by nature, and the distinctions between managed and unmanaged arrays warrant more information than other non-blittable types.

Управляемые массивыManaged Arrays

Управляемые массивы могут иметь разные типы, однако базовым для всех этих типов является класс System.Array.Managed array types can vary; however, the System.Array class is the base class of all array types. Класс System.Array имеет свойства, определяющие ранг, длину, нижнюю и верхнюю границы массива, а также методы доступа, сортировки, поиска, копирования и создания массивов.The System.Array class has properties for determining the rank, length, and lower and upper bounds of an array, as well as methods for accessing, sorting, searching, copying, and creating arrays.

Эти типы массивов являются динамическими и не имеют соответствующих статических типов в библиотеке базовых классов.These array types are dynamic and do not have a corresponding static type defined in the base class library. В качестве уникального типа массива удобно рассматривать сочетание типа элементов и ранга.It is convenient to think of each combination of element type and rank as a distinct type of array. Соответственно, тип одномерного массива целых чисел отличается от типа одномерного массива чисел типа double.Therefore, a one-dimensional array of integers is of a different type than a one-dimensional array of double types. Аналогичным образом, его тип будет отличаться от типа двухмерного массива целых чисел.Similarly a two-dimensional array of integers is different from a one-dimensional array of integers. При сравнении типов не учитываются границы массивов.The bounds of the array are not considered when comparing types.

Как показано в следующей таблице, любой экземпляр управляемого массива должен иметь заданные тип элементов, ранг и нижнюю границу.As the following table shows, any instance of a managed array must be of a specific element type, rank, and lower bound.

Тип управляемого массиваManaged array type Тип элементаElement type РангRank Нижняя границаLower bound Нотация сигнатурыSignature notation
ELEMENT_TYPE_ARRAYELEMENT_TYPE_ARRAY Задается по типу.Specified by type. Задается по рангу.Specified by rank. При необходимости задается границами.Optionally specified by bounds. type [ n,m ]type [ n,m ]
ELEMENT_TYPE_CLASSELEMENT_TYPE_CLASS НеизвестноUnknown НеизвестноUnknown НеизвестноUnknown System.ArraySystem.Array
ELEMENT_TYPE_SZARRAYELEMENT_TYPE_SZARRAY Задается по типу.Specified by type. 11 00 type [ n ]type [ n ]

Неуправляемые массивыUnmanaged Arrays

Неуправляемыми могут быть безопасные массивы в стиле COM или массивы в стиле C фиксированной или переменной длины.Unmanaged arrays are either COM-style safe arrays or C-style arrays with fixed or variable length. Безопасный массив — это описывающий сам себя массив, передающий тип, ранг и границы соответствующего массива данных.Safe arrays are self-describing arrays that carry the type, rank, and bounds of the associated array data. Массивы в стиле C — это одномерные типизированные массивы с фиксированной нижней границей, равной 0.C-style arrays are one-dimensional typed arrays with a fixed lower bound of 0. Служба маршалинга обеспечивает ограниченную поддержку обоих типов массивов.The marshaling service has limited support for both types of arrays.

Передача параметров массива в код .NETPassing Array Parameters to .NET Code

Массивы в стиле языка C и безопасные массивы могут передаваться в код .NET из неуправляемого кода в виде безопасных массивов или массивов в стиле C.Both C-style arrays and safe arrays can be passed to .NET code from unmanaged code as either a safe array or a C-style array. В следующей таблице показаны значения неуправляемого типа и соответствующих импортируемых типов.The following table shows the unmanaged type value and the imported type.

Неуправляемый типUnmanaged type Импортируемый типImported type
SafeArray( Type )SafeArray( Type ) ELEMENT_TYPE_SZARRAY < ConvertedType >ELEMENT_TYPE_SZARRAY < ConvertedType >

Ранг = 1, нижняя граница = 0.Rank = 1, lower bound = 0. Размер известен только в том случае, если он предоставлен в управляемой сигнатуре.Size is known only if provided in the managed signature. Безопасные массивы, ранг которых не равен 1, а нижняя граница не равна 0, не поддерживают маршалинг в виде SZARRAY.Safe arrays that are not rank = 1 or lower bound = 0 cannot be marshaled as SZARRAY.
Type []Type [] ELEMENT_TYPE_SZARRAY < ConvertedType >ELEMENT_TYPE_SZARRAY < ConvertedType >

Ранг = 1, нижняя граница = 0.Rank = 1, lower bound = 0. Размер известен только в том случае, если он предоставлен в управляемой сигнатуре.Size is known only if provided in the managed signature.

Безопасные массивыSafe Arrays

При импорте безопасного массива из библиотеки типов в сборку .NET он преобразуется в одномерный массив известного типа (например, int).When a safe array is imported from a type library to a .NET assembly, the array is converted to a one-dimensional array of a known type (such as int). К элементам массива применяются те же правила преобразования типов, что и к параметрам.The same type conversion rules that apply to parameters also apply to array elements. Например, безопасный массив типов BSTR преобразуется в управляемый массив строк, а безопасный массив вариантов — в управляемый массив объектов.For example, a safe array of BSTR types becomes a managed array of strings and a safe array of variants becomes a managed array of objects. Тип элементов SAFEARRAY получается из библиотеки типов и сохраняется в значении SAFEARRAY перечисления UnmanagedType.The SAFEARRAY element type is captured from the type library and saved in the SAFEARRAY value of the UnmanagedType enumeration.

Поскольку ранг и границы безопасного массива нельзя определить из библиотеки типов, предполагается, что ранг равен 1, а нижняя граница — 0.Because the rank and bounds of the safe array cannot be determined from the type library, the rank is assumed to equal 1 and the lower bound is assumed to equal 0. Ранг и границы должны быть определены в управляемой сигнатуре, которая создается с помощью программы импорта библиотек типов (Tlbimp.exe).The rank and bounds must be defined in the managed signature produced by the Type Library Importer (Tlbimp.exe). Если ранг, переданный в метод во время выполнения, отличается, возникает исключение SafeArrayRankMismatchException.If the rank passed to the method at run time differs, a SafeArrayRankMismatchException is thrown. Если тип массива, переданный во время выполнения, отличается, возникает исключение SafeArrayTypeMismatchException.If the type of the array passed at run time differs, a SafeArrayTypeMismatchException is thrown. В следующем примере показано применение безопасных массивов в управляемом и неуправляемом коде.The following example shows safe arrays in managed and unmanaged code.

Неуправляемая сигнатураUnmanaged signature

HRESULT New1([in] SAFEARRAY( int ) ar);  
HRESULT New2([in] SAFEARRAY( DATE ) ar);  
HRESULT New3([in, out] SAFEARRAY( BSTR ) *ar);  

Управляемая сигнатураManaged signature

Sub New1(<MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VT_I4)> _  
   ar() As Integer)  
Sub New2(<MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VT_DATE)> _   
   ar() As DateTime)  
Sub New3(ByRef <MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VT_BSTR)> _   
   ar() As String)  
void New1([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_I4)] int[] ar) ;  
void New2([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_DATE)]   
   DateTime[] ar);  
void New3([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_BSTR)]   
   ref String[] ar);  

Многомерные массивы или безопасные массивы с отличной от нуля границей могут маршалироваться в управляемый код, если сигнатура метода, создаваемая с помощью программы Tlbimp.exe, изменяется, указывая на тип элементов ELEMENT_TYPE_ARRAY вместо ELEMENT_TYPE_SZARRAY.Multidimensional, or nonzero-bound safe arrays, can be marshaled into managed code if the method signature produced by Tlbimp.exe is modified to indicate an element type of ELEMENT_TYPE_ARRAY instead of ELEMENT_TYPE_SZARRAY. Кроме того, можно использовать параметр /sysarray с программой Tlbimp.exe для импорта всех массивов в качестве объектов System.Array.Alternatively, you can use the /sysarray switch with Tlbimp.exe to import all arrays as System.Array objects. Если передаваемый массив заведомо является многомерным, можно изменить код MSIL, создаваемый программой Tlbimp.exe, а затем повторно скомпилировать его.In cases where the array being passed is known to be multidimensional, you can edit the Microsoft intermediate language (MSIL) code produced by Tlbimp.exe and then recompile it. Дополнительные сведения об изменении кода MSIL см. в разделе Настройка вызываемых оболочек времени выполнения.For details about how to modify MSIL code, see Customizing Runtime Callable Wrappers.

Массивы в стиле CC-Style Arrays

При импорте массива в стиле C из библиотеки типов в сборку .NET массив преобразуется в ELEMENT_TYPE_SZARRAY.When a C-style array is imported from a type library to a .NET assembly, the array is converted to ELEMENT_TYPE_SZARRAY.

Тип элемента массива определяется из библиотеки типов и сохраняется во время импорта.The array element type is determined from the type library and preserved during the import. К элементам массива применяются те же правила преобразования, что и к параметрам.The same conversion rules that apply to parameters also apply to array elements. Например, массив типов LPStr преобразуется в массив типов String.For example, an array of LPStr types becomes an array of String types. Программа Tlbimp.exe получает тип элементов массива и применяет к параметру атрибут MarshalAsAttribute.Tlbimp.exe captures the array element type and applies the MarshalAsAttribute attribute to the parameter.

Ранг массива принимается равным 1.The array rank is assumed to equal 1. Если ранг больше 1, массив маршалируется как одномерный массив в развертывании по столбцам.If the rank is greater than 1, the array is marshaled as a one-dimensional array in column-major order. Нижняя граница всегда равна 0.The lower bound always equals 0.

Библиотеки типов могут содержать массивы фиксированной или переменной длины.Type libraries can contain arrays of fixed or variable length. Поскольку в библиотеках типов содержится недостаточно информации для маршалинга массивов переменной длины, программа Tlbimp.exe может импортировать из них только массивы фиксированной длины.Tlbimp.exe can import only fixed-length arrays from type libraries because type libraries lack the information needed to marshal variable-length arrays. Для массивов фиксированной длины размер импортируется из библиотеки типов и сохраняется в атрибуте MarshalAsAttribute, который применяется к параметру.With fixed-length arrays, the size is imported from the type library and captured in the MarshalAsAttribute that is applied to the parameter.

Библиотеки типов, содержащие массивы переменной длины, необходимо определять вручную, как показано в следующем примере.You must manually define type libraries containing variable-length arrays, as shown in the following example.

Неуправляемая сигнатураUnmanaged signature

HRESULT New1(int ar[10]);  
HRESULT New2(double ar[10][20]);  
HRESULT New3(LPWStr ar[10]);  

Управляемая сигнатураManaged signature

Sub New1(<MarshalAs(UnmanagedType.LPArray, SizeConst=10)> _  
   ar() As Integer)  
Sub New2(<MarshalAs(UnmanagedType.LPArray, SizeConst=200)> _  
   ar() As Double)  
Sub New2(<MarshalAs(UnmanagedType.LPArray, _  
   ArraySubType=UnmanagedType.LPWStr, SizeConst=10)> _  
   ar() As String)  
void New1([MarshalAs(UnmanagedType.LPArray, SizeConst=10)] int[] ar);  
void New2([MarshalAs(UnmanagedType.LPArray, SizeConst=200)] double[] ar);  
void New2([MarshalAs(UnmanagedType.LPArray,   
   ArraySubType=UnmanagedType.LPWStr, SizeConst=10)] String[] ar);  

Несмотря на то, что с помощью атрибутов size_is или length_is массива в исходном коде на языке IDL можно передать сведения о размере клиенту, компилятор MIDL не передает эту информацию в библиотеку типов.Although you can apply the size_is or length_is attributes to an array in Interface Definition Language (IDL) source to convey the size to a client, the Microsoft Interface Definition Language (MIDL) compiler does not propagate that information to the type library. Не зная размера, служба маршалинга взаимодействия не может маршалировать элементы массива.Without knowing the size, the interop marshaling service cannot marshal the array elements. Таким образом, массивы переменной длины импортируются в виде ссылочных аргументов.Consequently, variable-length arrays are imported as reference arguments. Например:For example:

Неуправляемая сигнатураUnmanaged signature

HRESULT New1(int ar[]);  
HRESULT New2(int ArSize, [size_is(ArSize)] double ar[]);  
HRESULT New3(int ElemCnt, [length_is(ElemCnt)] LPStr ar[]);  

Управляемая сигнатураManaged signature

Sub New1(ByRef ar As Integer)  
Sub New2(ByRef ar As Double)  
Sub New3(ByRef ar As String)  
void New1(ref int ar);    
void New2(ref double ar);    
void New3(ref String ar);   

Чтобы предоставить размер массива маршалеру, можно изменить код на языке MSIL, создаваемый программой Tlbimp.exe, после чего повторно скомпилировать его.You can provide the marshaler with the array size by editing the Microsoft intermediate language (MSIL) code produced by Tlbimp.exe and then recompiling it. Дополнительные сведения об изменении кода MSIL см. в разделе Настройка вызываемых оболочек времени выполнения.For details about how to modify MSIL code, see Customizing Runtime Callable Wrappers. Чтобы указать число элементов в массиве, примените тип MarshalAsAttribute к параметру массива в определении управляемого метода одним из следующих способов:To indicate the number of elements in the array, apply the MarshalAsAttribute type to the array parameter of the managed method definition in one of the following ways:

  • Определите еще один параметр, который содержит число элементов в массиве.Identify another parameter that contains the number of elements in the array. Параметры определяются по позиции, начиная с первого, который получает номер 0.The parameters are identified by position, starting with the first parameter as number 0.

    Sub [New](ElemCnt As Integer, _  
       \<MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> _  
       ar() As Integer)  
    
    void New(  
       int ElemCnt,   
       [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] int[] ar );  
    
  • Определите размер массива в виде константы.Define the size of the array as a constant. Например:For example:

    Sub [New](\<MarshalAs(UnmanagedType.LPArray, SizeConst:=128)> _  
       ar() As Integer)  
    
    void New(  
       [MarshalAs(UnmanagedType.LPArray, SizeConst=128)] int[] ar );  
    

При маршалинге массивов из неуправляемого в управляемый код маршалер проверяет связанный с параметром атрибут MarshalAsAttribute, чтобы определить размер массива.When marshaling arrays from unmanaged code to managed code, the marshaler checks the MarshalAsAttribute associated with the parameter to determine the array size. Если размер массива не указан, выполняется маршалинг только одного элемента.If the array size is not specified, only one element is marshaled.

Примечание

Атрибут MarshalAsAttribute не учитывается при маршалинге управляемых массивов в неуправляемый код.The MarshalAsAttribute has no effect on marshaling managed arrays to unmanaged code. В этом направлении размер массива определяется с помощью проверки.In that direction, the array size is determined by examination. Маршалинг подмножества управляемого массива невозможен.There is no way to marshal a subset of a managed array.

Маршалер взаимодействия использует методы CoTaskMemAlloc и CoTaskMemFree для выделения и высвобождения памяти.The interop marshaler uses the CoTaskMemAlloc and CoTaskMemFree methods to allocate and retrieve memory. Эти методы также необходимо использовать при выделении памяти в неуправляемом коде.Memory allocation performed by unmanaged code must also use these methods.

Передача массивов в COMPassing Arrays to COM

Все типы управляемых массивов можно передавать в неуправляемый код из управляемого кода.All managed array types can be passed to unmanaged code from managed code. В зависимости от управляемого типа и примененных к нему атрибутов, доступ к массиву осуществляется как к безопасному массиву или как к массиву в стиле C, как показано в следующей таблице.Depending on the managed type and the attributes applied to it, the array can be accessed as a safe array or a C-style array, as shown in the following table.

Тип управляемого массиваManaged array type Экспортируется какExported as
ELEMENT_TYPE_SZARRAY < type >ELEMENT_TYPE_SZARRAY < type > UnmanagedType .SafeArray( type )UnmanagedType .SafeArray( type )

UnmanagedType.LPArrayUnmanagedType.LPArray

Тип предоставляется в сигнатуре.Type is provided in the signature. Ранг всегда равен 1, а нижняя граница всегда — 0.Rank is always 1, lower bound is always 0. Размер всегда известен во время выполнения.Size is always known at run time.
ELEMENT_TYPE_ARRAY < type > < rank > [ < bounds > ]ELEMENT_TYPE_ARRAY < type > < rank >[< bounds >] UnmanagedType.SafeArray( type )UnmanagedType.SafeArray( type )

UnmanagedType.LPArrayUnmanagedType.LPArray

Тип, ранг и границы предоставляются в сигнатуре.Type, rank, bounds are provided in the signature. Размер всегда известен во время выполнения.Size is always known at run time.
ELEMENT_TYPE_CLASS < System.Array >ELEMENT_TYPE_CLASS <System.Array> UT_InterfaceUT_Interface

UnmanagedType.SafeArray( type )UnmanagedType.SafeArray( type )

Тип, ранг, границы и размер всегда известны во время выполнения.Type, rank, bounds, and size are always known at run time.

В OLE-автоматизации существует ограничение в отношении массивов структур, которые содержат LPSTR или LPWSTR.There is a limitation in OLE Automation relating to arrays of structures that contain LPSTR or LPWSTR. Таким образом, поля String должны маршалироваться как UnmanagedType.BSTR.Therefore, String fields have to be marshaled as UnmanagedType.BSTR. В противном случае будет создаваться исключение.Otherwise, an exception will be thrown.

ELEMENT_TYPE_SZARRAYELEMENT_TYPE_SZARRAY

При экспорте метода, содержащего параметр ELEMENT_TYPE_SZARRAY (одномерный массив), из сборки .NET в библиотеку типов параметр массива преобразуется в массив SAFEARRAY заданного типа.When a method containing an ELEMENT_TYPE_SZARRAY parameter (one-dimensional array) is exported from a .NET assembly to a type library, the array parameter is converted to a SAFEARRAY of a given type. Те же правила преобразования применяются к типам элементов массива.The same conversion rules apply to the array element types. Содержимое управляемого массива автоматически копируется из управляемой памяти в SAFEARRAY.The contents of the managed array are automatically copied from managed memory into the SAFEARRAY. Например:For example:

Управляемая сигнатураManaged signature

Sub [New](ar() As Long)  
Sub [New](ar() As String)  
void New(long[] ar );  
void New(String[] ar );  

Неуправляемая сигнатураUnmanaged signature

HRESULT New([in] SAFEARRAY( long ) ar);
HRESULT New([in] SAFEARRAY( BSTR ) ar);  

Ранг безопасных массивов всегда равен 1, а нижняя граница —0.The rank of the safe arrays is always 1 and the lower bound is always 0. Размер определяется во время выполнения на основе размера передаваемого управляемого массива.The size is determined at run time by the size of the managed array being passed.

Массив также может маршалироваться как массив в стиле C с помощью атрибута MarshalAsAttribute.The array can also be marshaled as a C-style array by using the MarshalAsAttribute attribute. Например:For example:

Управляемая сигнатураManaged signature

Sub [New](<MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> _  
   ar() As Long, size as Integer)  
Sub [New](<MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> _  
   ar() As String, size as Integer)  
Sub [New](<MarshalAs(UnmanagedType.LPArray, _  
   ArraySubType= UnmanagedType.LPStr, SizeParamIndex:=1)> _  
   ar() As String, size as Integer)  
void New([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]   
   long [] ar, int size );  
void New([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]   
   String [] ar, int size );  
void New([MarshalAs(UnmanagedType.LPArray, ArraySubType=   
   UnmanagedType.LPStr, SizeParamIndex=1)]   
   String [] ar, int size );  

Неуправляемая сигнатураUnmanaged signature

HRESULT New(long ar[]);
HRESULT New(BSTR ar[]);
HRESULT New(LPStr ar[]);  

Несмотря на то, что маршалеру известна длина, необходимая для маршалинга массива, длина массива обычно передается вызываемому объекту в отдельном аргументе.Although the marshaler has the length information needed to marshal the array, the array length is usually passed as a separate argument to convey the length to the callee.

ELEMENT_TYPE_ARRAYELEMENT_TYPE_ARRAY

При экспорте метода, содержащего параметр ELEMENT_TYPE_ARRAY, из сборки .NET в библиотеку типов параметр массива преобразуется в массив SAFEARRAY заданного типа.When a method containing an ELEMENT_TYPE_ARRAY parameter is exported from a .NET assembly to a type library, the array parameter is converted to a SAFEARRAY of a given type. Содержимое управляемого массива автоматически копируется из управляемой памяти в SAFEARRAY.The contents of the managed array are automatically copied from managed memory into the SAFEARRAY. Например:For example:

Управляемая сигнатураManaged signature

Sub [New](ar(,) As Long)  
Sub [New](ar(,) As String)  
void New( long [,] ar );  
void New( String [,] ar );  

Неуправляемая сигнатураUnmanaged signature

HRESULT New([in] SAFEARRAY( long ) ar);
HRESULT New([in] SAFEARRAY( BSTR ) ar);  

Ранг, размер и границы безопасного массива определяются во время выполнения на основе характеристик управляемого массива.The rank, size, and bounds of the safe arrays are determined at run time by the characteristics of the managed array.

Массив также может маршалироваться как массив в стиле C с помощью атрибута MarshalAsAttribute.The array can also be marshaled as a C-style array by applying the MarshalAsAttribute attribute. Например:For example:

Управляемая сигнатураManaged signature

Sub [New](<MarshalAs(UnmanagedType.LPARRAY, SizeParamIndex:=1)> _  
   ar(,) As Long, size As Integer)  
Sub [New](<MarshalAs(UnmanagedType.LPARRAY, _  
   ArraySubType:=UnmanagedType.LPStr, SizeParamIndex:=1)> _  
   ar(,) As String, size As Integer)  
void New([MarshalAs(UnmanagedType.LPARRAY, SizeParamIndex=1)]   
   long [,] ar, int size );  
void New([MarshalAs(UnmanagedType.LPARRAY,   
   ArraySubType= UnmanagedType.LPStr, SizeParamIndex=1)]   
   String [,] ar, int size );  

Неуправляемая сигнатураUnmanaged signature

HRESULT New(long ar[]);
HRESULT New(LPStr ar[]);  

Вложенные массивы не поддерживают маршалирование.Nested arrays cannot be marshaled. Например, при экспорте с использованием программы экспорта библиотеки типов (Tlbexp.exe) следующая сигнатура приводит к возникновению ошибки.For example, the following signature generates an error when exported with the Type Library Exporter (Tlbexp.exe).

Управляемая сигнатураManaged signature

Sub [New](ar()()() As Long)  
void New(long [][][] ar );  

ELEMENT_TYPE_CLASS <System.Array>ELEMENT_TYPE_CLASS <System.Array>

При экспорте метода, содержащего параметр System.Array, из сборки .NET в библиотеку типов параметр массива преобразуется в интерфейс _Array.When a method containing a System.Array parameter is exported from a .NET assembly to a type library, the array parameter is converted to an _Array interface. Содержимое этого управляемого массива доступно только через методы и свойства интерфейса _Array.The contents of the managed array are accessible only through the methods and properties of the _Array interface. Массив System.Array также может маршалироваться как SAFEARRAY с помощью атрибута MarshalAsAttribute.System.Array can also be marshaled as a SAFEARRAY by using the MarshalAsAttribute attribute. При маршалинге безопасного массива его элементы маршалируются как варианты.When marshaled as a safe array, the array elements are marshaled as variants. Например:For example:

Управляемая сигнатураManaged signature

Sub New1( ar As System.Array )  
Sub New2( <MarshalAs(UnmanagedType.Safe array)> ar As System.Array )  
void New1( System.Array ar );  
void New2( [MarshalAs(UnmanagedType.Safe array)] System.Array ar );  

Неуправляемая сигнатураUnmanaged signature

HRESULT New([in] _Array *ar);
HRESULT New([in] SAFEARRAY(VARIANT) ar);  

Массивы внутри структурArrays within Structures

Неуправляемые структуры могут содержать вложенные массивы.Unmanaged structures can contain embedded arrays. По умолчанию эти вложенные поля массива маршалируются как SAFEARRAY.By default, these embedded array fields are marshaled as a SAFEARRAY. В следующем примере s1 — это вложенный массив, который выделяется непосредственно в структуре.In the following example, s1 is an embedded array that is allocated directly within the structure itself.

Неуправляемое представлениеUnmanaged representation

struct MyStruct {  
    short s1[128];  
}  

Массивы могут маршалироваться как UnmanagedType, для чего необходимо установить поле MarshalAsAttribute.Arrays can be marshaled as UnmanagedType, which requires you to set the MarshalAsAttribute field. Размер может задаваться только в виде константы.The size can be set only as a constant. В коде ниже показаны соответствующие управляемые определения MyStruct.The following code shows the corresponding managed definition of MyStruct.

Public Structure <StructLayout(LayoutKind.Sequential)> MyStruct  
   Public <MarshalAs(UnmanagedType.ByValArray, SizeConst := 128)> _  
     s1() As Short  
End Structure  
[StructLayout(LayoutKind.Sequential)]  
public struct MyStruct {  
   [MarshalAs(UnmanagedType.ByValArray, SizeConst=128)] public short[] s1;  
}  

См. такжеSee also