Standardmäßiges Marshalling für ArraysDefault Marshaling for Arrays

In einer Anwendung, die vollständig aus verwaltetem Code besteht, übergibt die Common Language Runtime Arraytypen als In-/Out-Parameter.In an application consisting entirely of managed code, the common language runtime passes array types as In/Out parameters. Im Gegensatz dazu übergibt der Interopmarshaller außerdem ein Array als In-Parameter in der Standardeinstellung.In contrast, the interop marshaler passes an array as In parameters by default.

Bei der pinning optimization (Fixierungsoptimierung),kann ein blitfähiges Array den Anschein erwecken, dass es als In/Out-Parameter fungiert, wenn es mit Objekten in demselben Apartment interagiert.With pinning optimization, a blittable array can appear to operate as an In/Out parameter when interacting with objects in the same apartment. Wenn Sie allerdings den Code später in eine Typbibliothek exportieren, mit der der computerübergreifende Proxy generiert wird, und diese Bibliothek dazu verwendet wird, Ihre Aufrufe über Apartments hinweg zu marshallen, können sich die Aufrufe wieder wie TRUE-Parameter verhalten.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 sind naturgemäß komplex, und die Unterschiede zwischen verwalteten und nicht verwalteten Arrays bieten mehr Informationen als andere nicht blitfähige Typen.Arrays are complex by nature, and the distinctions between managed and unmanaged arrays warrant more information than other non-blittable types.

Verwaltete ArraysManaged Arrays

Verwaltete Arraytypen können variieren. Allerdings ist die System.Array-Klasse die Basisklasse für alle Arraytypen.Managed array types can vary; however, the System.Array class is the base class of all array types. Die System.Array-Klasse enthält Eigenschaften, um den Rang, die Länge und die Unter- und Obergrenze eines Arrays zu bestimmen, als auch Methoden zum Zugreifen, Sortieren, Durchsuchen, Kopieren und Erstellen von Arrays.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.

Diese Arraytypen sind dynamisch und verfügen über keinen entsprechenden statischen, in der Basisklassenbibliothek definierten Typen.These array types are dynamic and do not have a corresponding static type defined in the base class library. Es ist sinnvoll, jede Kombination aus Elementtyp und Rang als gesonderten Arraytypen zu betrachten.It is convenient to think of each combination of element type and rank as a distinct type of array. Deshalb unterscheidet sich ein eindimensionales Array von ganzen Zahlen von einem eindimensionalen Array von Double-Typen.Therefore, a one-dimensional array of integers is of a different type than a one-dimensional array of double types. In ähnlicher Weise unterscheidet sich ein zweidimensionales Array von ganzen Zahlen von einem eindimensionalen Array von ganzen Zahlen.Similarly a two-dimensional array of integers is different from a one-dimensional array of integers. Die Grenzen des Arrays werden beim Vergleichen von Typen nicht berücksichtigt.The bounds of the array are not considered when comparing types.

Wie die folgende Tabelle zeigt, muss jede Instanz eines verwalteten Arrays über einen bestimmter Elementtyp, Rang und eine bestimmte Untergrenze verfügen.As the following table shows, any instance of a managed array must be of a specific element type, rank, and lower bound.

Verwalteter ArraytypManaged array type ElementtypElement type RangRank Unterer GrenzwertLower bound SignaturschreibweiseSignature notation
ELEMENT_TYPE_ARRAYELEMENT_TYPE_ARRAY Durch den Typ angegeben.Specified by type. Durch den Rang angegeben.Specified by rank. Optional durch Grenzen angegeben.Optionally specified by bounds. Typ [ n,m ]type [ n,m ]
ELEMENT_TYPE_CLASSELEMENT_TYPE_CLASS UnbekanntUnknown UnbekanntUnknown UnbekanntUnknown System.ArraySystem.Array
ELEMENT_TYPE_SZARRAYELEMENT_TYPE_SZARRAY Durch den Typ angegeben.Specified by type. 11 00 Typ [ n ]type [ n ]

Nicht verwaltete ArraysUnmanaged Arrays

Nicht verwaltete Arrays sind entweder sichere Arrays im COM-Stil oder Arrays im C-Stil mit fester oder variabler Länge.Unmanaged arrays are either COM-style safe arrays or C-style arrays with fixed or variable length. Sichere Arrays sind selbstbeschreibende Arrays, die den Typ, den Rang und die Grenzen der verknüpften Arraydaten enthalten.Safe arrays are self-describing arrays that carry the type, rank, and bounds of the associated array data. Arrays im C-Stil sind eindimensionale typisierte Arrays mit einer festen Untergrenze von 0.C-style arrays are one-dimensional typed arrays with a fixed lower bound of 0. Der Marshallingdienst bietet nur eingeschränkt Unterstützung für beide Typen von Arrays.The marshaling service has limited support for both types of arrays.

Übergeben von Arrayparametern an .NET-CodePassing Array Parameters to .NET Code

Arrays im C-Stil und sichere Arrays, können aus nicht verwaltetem Code an .NET-Code, als ein sicheres Array oder ein Array im C-Stil übergeben werden.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. Die folgende Tabelle zeigt den nicht verwalteten Typwert und den importierten Typ.The following table shows the unmanaged type value and the imported type.

Nicht verwalteter TypUnmanaged type Importierter TypImported type
SafeArray( Typ )SafeArray( Type ) ELEMENT_TYPE_SZARRAY < KonvertierterTyp >ELEMENT_TYPE_SZARRAY < ConvertedType >

Rang = 1, Untergrenze = 0.Rank = 1, lower bound = 0. Die Größe ist nur bekannt, wenn sie in der verwalteten Signatur bereitgestellt wird.Size is known only if provided in the managed signature. Sichere Arrays, bei denen Rang = 1 oder Untergrenze = 0 nicht gilt, können nicht als SZARRAY gemarshallt werden.Safe arrays that are not rank = 1 or lower bound = 0 cannot be marshaled as SZARRAY.
Typ []Type [] ELEMENT_TYPE_SZARRAY < KonvertierterTyp >ELEMENT_TYPE_SZARRAY < ConvertedType >

Rang = 1, Untergrenze = 0.Rank = 1, lower bound = 0. Die Größe ist nur bekannt, wenn sie in der verwalteten Signatur bereitgestellt wird.Size is known only if provided in the managed signature.

Sichere ArraysSafe Arrays

Wenn ein sicheres Array aus einer Typbibliothek in eine .NET-Assembly importiert wird, wird das Array in ein eindimensionales Array eines bekannten Typs konvertiert (z.B. 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). Dieselben Typkonvertierungsregeln, die für Parameter gelten, gelten auch für Arrayelemente.The same type conversion rules that apply to parameters also apply to array elements. So wird beispielsweise ein sicheres Array von BSTR-Typen zu einem verwalteten Array von Zeichenfolgen, und ein sicheres Array von Varianten zu einem verwalteten Array von Objekten.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. Der SAFEARRAY-Elementtyp wird aus der Typbibliothek abgerufen, und im SAFEARRAY-Wert der UnmanagedType-Enumeration gespeichert.The SAFEARRAY element type is captured from the type library and saved in the SAFEARRAY value of the UnmanagedType enumeration.

Da Rang und Grenzen eines sicheren Arrays über die Typbibliothek nicht bestimmt werden können, wird für den Rang ein Wert von 1 und für die Untergrenze ein Wert von 0 angenommen.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. Rang und Grenzen müssen in der vom Type Library Importer (Tlbimp.exe) (Typbibliothek Importer) erzeugten verwalteten Signatur definiert werden.The rank and bounds must be defined in the managed signature produced by the Type Library Importer (Tlbimp.exe). Wenn der zur Laufzeit an die Methode übergebene Rang unterschiedlich ist, wird eine SafeArrayRankMismatchException ausgelöst.If the rank passed to the method at run time differs, a SafeArrayRankMismatchException is thrown. Wenn der zur Laufzeit übergebene Arraytyp unterschiedlich ist, wird eine SafeArrayTypeMismatchException ausgelöst.If the type of the array passed at run time differs, a SafeArrayTypeMismatchException is thrown. Das folgende Beispiel zeigt sichere Arrays in verwaltetem und nicht verwaltetem Code.The following example shows safe arrays in managed and unmanaged code.

Nicht verwaltete SignaturUnmanaged signature

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

Verwaltete SignaturManaged 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);  

Mehrdimensionale oder gebundene sichere Arrays mit einem Wert ungleich null, können in verwalteten Code gemarshallt werden, wenn die von Tlbimp.exe erzeugte Methodensignatur so geändert wird, dass sie einen Elementtyp von ELEMENT_TYPE_ARRAY anstelle von ELEMENT_TYPE_SZARRAY angibt.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. Alternativ können Sie den /sysarray -Schalter mit Tlbimp.exe verwenden, um alle Arrays als System.Array-Objekte zu importieren.Alternatively, you can use the /sysarray switch with Tlbimp.exe to import all arrays as System.Array objects. Wenn bekannt ist, dass das übergebene Array mehrdimensional ist, können Sie den durch Tlbimp.exeMicrosoft erzeugten Intermediate Language-Code (MSIL) bearbeiten, und diesen anschließend neu kompilieren.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. Ausführliche Informationen zum Ändern des MSIL-Codes finden Sie unter Customizing Runtime Callable Wrappers (Anpassen von durch die Laufzeit aufrufbaren Wrappern).For details about how to modify MSIL code, see Customizing Runtime Callable Wrappers.

Arrays im C-StilC-Style Arrays

Wenn ein Array im C-Stil aus einer Typbibliothek in eine .NET Framework-Assembly importiert wird, wird das Array in ELEMENT_TYPE_SZARRAY konvertiert.When a C-style array is imported from a type library to a .NET assembly, the array is converted to ELEMENT_TYPE_SZARRAY.

Der Elementtyp des Arrays wird durch die Typbibliothek bestimmt und während des Imports beibehalten.The array element type is determined from the type library and preserved during the import. Dieselben Konvertierungsregeln, die für Parameter gelten, gelten auch für Arrayelemente.The same conversion rules that apply to parameters also apply to array elements. Ein Array von LPStr-Typen wird z.B. zu einem Array von Zeichenfolge-Typen.For example, an array of LPStr types becomes an array of String types. Tlbimp.exe erfasst den Elementtyp des Arrays und wendet das MarshalAsAttribute-Attribut auf den Parameter an.Tlbimp.exe captures the array element type and applies the MarshalAsAttribute attribute to the parameter.

Es wird angenommen, dass der Rang des Arrays gleich 1 ist.The array rank is assumed to equal 1. Wenn der Rang größer als 1 ist, wird das Array als eindimensionales Array nach Spaltengröße gemarshallt.If the rank is greater than 1, the array is marshaled as a one-dimensional array in column-major order. Die Untergrenze ist immer gleich 0.The lower bound always equals 0.

Typbibliotheken können Arrays mit fester oder variabler Länge enthalten.Type libraries can contain arrays of fixed or variable length. Tlbimp.exe kann nur Arrays mit fester Länge aus Typbibliotheken importieren, da Typbibliotheken nicht die benötigten Informationen zum Marshallen von Arrays mit variabler Länge enthalten.Tlbimp.exe can import only fixed-length arrays from type libraries because type libraries lack the information needed to marshal variable-length arrays. Bei Arrays mit fester Länge, wird die Größe aus der Typbibliothek importiert und im MarshalAsAttribute, das auf den Parameter angewendet wird, erfasst.With fixed-length arrays, the size is imported from the type library and captured in the MarshalAsAttribute that is applied to the parameter.

Typbibliotheken, die Arrays mit variabler Länge beinhalten müssen, wie in folgendem Beispiel gezeigt, manuell definiert werden.You must manually define type libraries containing variable-length arrays, as shown in the following example.

Nicht verwaltete SignaturUnmanaged signature

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

Verwaltete SignaturManaged 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);  

Obwohl Sie das Size_is- oder Length_is-Attribut auf ein Array in der Interface Definition Language (IDL)-Quelle anwenden können, um einem Client die Größe mitzuteilen, übermittelt der Microsoft Interface Definition Language (MIDL)-Compiler diese Information nicht an die Typbibliothek.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. Ohne die Größe zu kennen, kann der Interop-Marshallingdienst die Arrayelemente nicht marshallen.Without knowing the size, the interop marshaling service cannot marshal the array elements. Folglich werden Arrays mit variabler Länge als Verweisargumente importiert.Consequently, variable-length arrays are imported as reference arguments. Beispiel:For example:

Nicht verwaltete SignaturUnmanaged signature

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

Verwaltete SignaturManaged 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);   

Sie können die Arraygröße für den Marshaller bereitstellen, indem Sie den durch Tlbimp.exe erzeugten Microsoft intermediate Language-Code (MSIL) bearbeiten und anschließend neu kompilieren.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. Ausführliche Informationen zum Ändern des MSIL-Codes finden Sie unter Customizing Runtime Callable Wrappers (Anpassen von durch die Laufzeit aufrufbaren Wrappern).For details about how to modify MSIL code, see Customizing Runtime Callable Wrappers. Um die Anzahl der Elemente im Array anzuzeigen, wenden Sie den MarshalAsAttribute-Typ auf den Arrayparameter der verwalteten Methodendefinition durch eine der folgenden Vorgehensweisen an: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:

  • Geben Sie einen weiteren Parameter an, der die Anzahl der Elemente im Array enthält.Identify another parameter that contains the number of elements in the array. Die Parameter werden anhand der Position bestimmt, beginnend mit dem ersten Parameter als Nummer 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 );  
    
  • Definieren Sie die Größe des Arrays als Konstante.Define the size of the array as a constant. Beispiel:For example:

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

Beim Marshallen von Arrays aus nicht verwaltetem Code an verwalteten Code überprüft der Marshaller das dem Parameter zugeordnete MarshalAsAttribute, um die Arraygröße zu bestimmen.When marshaling arrays from unmanaged code to managed code, the marshaler checks the MarshalAsAttribute associated with the parameter to determine the array size. Wenn die Größe des Arrays nicht angegeben ist, wird nur ein Element gemarshallt.If the array size is not specified, only one element is marshaled.

Hinweis

Das Attribut MarshalAsAttribute wirkt sich nicht auf das Marshallen verwalteter Arrays an nicht verwalteten Code aus.The MarshalAsAttribute has no effect on marshaling managed arrays to unmanaged code. In dieser Richtung wird die Arraygröße durch Prüfung bestimmt.In that direction, the array size is determined by examination. Es besteht keine Möglichkeit, einen Teil eines verwalteten Arrays zu marshallen.There is no way to marshal a subset of a managed array.

Der Interop-Marshaller verwendet die CoTaskMemAlloc- und CoTaskMemFree-Methoden, um Speicherplatz zu belegen und abzurufen.The interop marshaler uses the CoTaskMemAlloc and CoTaskMemFree methods to allocate and retrieve memory. Diese Methoden müssen auch bei der Speicherbelegung durch nicht verwalteten Code verwendet werden.Memory allocation performed by unmanaged code must also use these methods.

Übergeben von Arrays an COMPassing Arrays to COM

Alle verwalteten Arraytypen können von verwaltetem Code an nicht verwalteten Code übergeben werden.All managed array types can be passed to unmanaged code from managed code. Abhängig vom verwalteten Typ und den auf diesen Typ angewendeten Attributen, kann, wie in der folgenden Tabelle gezeigt, das Array als sicheres Array oder als Array im C-Stil abgerufen werden.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.

Verwalteter ArraytypManaged array type Exportiert alsExported as
ELEMENT_TYPE_SZARRAY < Typ >ELEMENT_TYPE_SZARRAY < type > UnmanagedType .SafeArray( Typ )UnmanagedType .SafeArray( type )

UnmanagedType.LPArrayUnmanagedType.LPArray

Typ wird in der Signatur angegeben.Type is provided in the signature. Rang ist immer 1, Untergrenze ist immer 0.Rank is always 1, lower bound is always 0. Größe ist immer zur Laufzeit bekannt.Size is always known at run time.
ELEMENT_TYPE_ARRAY < Typ > < Rang >[< Grenzen >]ELEMENT_TYPE_ARRAY < type > < rank >[< bounds >] UnmanagedType.SafeArray( Typ )UnmanagedType.SafeArray( type )

UnmanagedType.LPArrayUnmanagedType.LPArray

Typ, Rang und Grenzen sind in der Signatur angegeben.Type, rank, bounds are provided in the signature. Die Größe ist immer zur Laufzeit bekannt.Size is always known at run time.
ELEMENT_TYPE_CLASS <System.Array>ELEMENT_TYPE_CLASS <System.Array> UT_InterfaceUT_Interface

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

Typ, Rang, Grenzen und Größe sind immer zur Laufzeit bekannt.Type, rank, bounds, and size are always known at run time.

In der OLE-Automatisierung, gibt es im Zusammenhang mit Arrays von Strukturen, die LPSTR oder LPWSTR enthalten eine Einschränkung.There is a limitation in OLE Automation relating to arrays of structures that contain LPSTR or LPWSTR. Aus diesem Grund müssen Zeichenfolge-Felder als UnmanagedType.BSTR gemarshallt werden.Therefore, String fields have to be marshaled as UnmanagedType.BSTR. Andernfalls wird eine Ausnahme ausgelöst.Otherwise, an exception will be thrown.

ELEMENT_TYPE_SZARRAYELEMENT_TYPE_SZARRAY

Wenn eine Methode mit einem ELEMENT_TYPE_SZARRAY-Parameter (eindimensionales Array) aus einer .NET-Assembly in eine Typbibliothek exportiert wird, wird der Arrayparameter in ein SAFEARRAY eines gegebenen Typs konvertiert.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. Dieselben Konvertierungsregeln gelten für die Arrayelementtypen.The same conversion rules apply to the array element types. Der Inhalt des verwalteten Arrays wird automatisch aus dem verwalteten Speicher in das SAFEARRAY kopiert.The contents of the managed array are automatically copied from managed memory into the SAFEARRAY. Beispiel:For example:

Verwaltete SignaturManaged signature

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

Nicht verwaltete SignaturUnmanaged signature

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

Der Rang eines sicheren Arrays ist immer 1, und die Untergrenze ist immer 0.The rank of the safe arrays is always 1 and the lower bound is always 0. Die Größe wird zur Laufzeit durch die Größe des übergebenen verwalteten Arrays bestimmt.The size is determined at run time by the size of the managed array being passed.

Das Array kann auch als Array im C-Stil, mithilfe des MarshalAsAttribute-Attributs gemarshallt werden.The array can also be marshaled as a C-style array by using the MarshalAsAttribute attribute. Beispiel:For example:

Verwaltete SignaturManaged 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 );  

Nicht verwaltete SignaturUnmanaged signature

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

Obwohl der Marshaller die erforderlichen Längeninformationen zum Marshallen von Arrays hat, wird die Länge des Arrays in der Regel als separates Argument übergeben, um dem Aufgerufenen die Länge mitzuteilen.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

Wenn eine Methode mit einem ELEMENT_TYPE_ARRAY-Parameter aus einer .NET-Assembly in eine Typbibliothek exportiert wird, wird der Arrayparameter in ein SAFEARRAY eines gegebenen Typs konvertiert.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. Der Inhalt des verwalteten Arrays wird automatisch aus dem verwalteten Speicher in das SAFEARRAY kopiert.The contents of the managed array are automatically copied from managed memory into the SAFEARRAY. Beispiel:For example:

Verwaltete SignaturManaged signature

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

Nicht verwaltete SignaturUnmanaged signature

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

Der Rang, die Größe und die Grenzen eines sicheren Arrays werden zur Laufzeit durch die Merkmale des verwalteten Arrays bestimmt.The rank, size, and bounds of the safe arrays are determined at run time by the characteristics of the managed array.

Das Array kann auch als Array im C-Stil, mithilfe des MarshalAsAttribute-Attributs gemarshallt werden.The array can also be marshaled as a C-style array by applying the MarshalAsAttribute attribute. Beispiel:For example:

Verwaltete SignaturManaged 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 );  

Nicht verwaltete SignaturUnmanaged signature

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

Geschachtelte Arrays können nicht gemarshallt werden.Nested arrays cannot be marshaled. Die folgende Signatur generiert beispielsweise einen Fehler, wenn sie mit dem Type Library Exporter (Tlbexp.exe) exportiert wird.For example, the following signature generates an error when exported with the Type Library Exporter (Tlbexp.exe).

Verwaltete SignaturManaged signature

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

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

Wenn eine Methode, die einen System.Array-Parameter enthält aus einer .NET-Assembly in eine Typbibliothek exportiert wird, wird der Arrayparameter in eine _Array-Schnittstelle konvertiert.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. Auf den Inhalt des verwalteten Arrays kann nur über die Methoden und Eigenschaften der _Array-Schnittstelle zugegriffen werden.The contents of the managed array are accessible only through the methods and properties of the _Array interface. System.Array kann auch als SAFEARRAY, mithilfe von MarshalAsAttribute-Attributen gemarshallt werden.System.Array can also be marshaled as a SAFEARRAY by using the MarshalAsAttribute attribute. Wenn die Arrayelemente als sicheres Array gemarshallt werden, werden sie als Varianten gemarshallt.When marshaled as a safe array, the array elements are marshaled as variants. Beispiel:For example:

Verwaltete SignaturManaged 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 );  

Nicht verwaltete SignaturUnmanaged signature

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

Arrays in StrukturenArrays within Structures

Nicht verwaltete Strukturen können eingebettete Arrays enthalten.Unmanaged structures can contain embedded arrays. Standardmäßig werden diese eingebetteten Arrayfelder als SAFEARRAY gemarshallt.By default, these embedded array fields are marshaled as a SAFEARRAY. Im folgenden Beispiel ist s1 ein eingebettetes Array, das direkt innerhalb der Struktur selbst zugeordnet ist.In the following example, s1 is an embedded array that is allocated directly within the structure itself.

Nicht verwalteten DarstellungUnmanaged representation

struct MyStruct {  
    short s1[128];  
}  

Arrays können als UnmanagedType gemarshallt sein, was das Einrichten des MarshalAsAttribute-Felds voraussetzt.Arrays can be marshaled as UnmanagedType, which requires you to set the MarshalAsAttribute field. Die Größe kann nur als eine Konstante festgelegt werden.The size can be set only as a constant. Der folgende Code zeigt die entsprechende verwaltete Definition von 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;  
}  

Siehe auchSee also