Marshaling par défaut pour les tableauxDefault Marshaling for Arrays

Dans une application composée dans son ensemble de code managé, le common language runtime passe des types tableau comme paramètres en entrée/sortie.In an application consisting entirely of managed code, the common language runtime passes array types as In/Out parameters. Par contre, le marshaleur d’interopérabilité passe un tableau comme paramètre en entrée par défaut.In contrast, the interop marshaler passes an array as In parameters by default.

Avec l’optimisation de l’épinglage, un tableau blittable peut sembler s’exécuter en tant que paramètre en entrée/sortie quand il interagit avec des objets dans le même cloisonnement.With pinning optimization, a blittable array can appear to operate as an In/Out parameter when interacting with objects in the same apartment. Toutefois, si vous exportez ultérieurement le code dans une bibliothèque de types utilisée pour générer le proxy entre ordinateurs et que la bibliothèque est utilisée pour marshaler vos appels entre cloisonnements, les appels peuvent revenir à un vrai comportement de paramètre en entrée.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.

Les tableaux sont par nature complexes et les distinctions entre les tableaux managés et non managés justifient davantage d’informations que les autres types non blittables.Arrays are complex by nature, and the distinctions between managed and unmanaged arrays warrant more information than other non-blittable types.

Tableaux managésManaged Arrays

Les types tableau managés sont divers ; cependant, la classe System.Array est la classe de base de tous les types tableau.Managed array types can vary; however, the System.Array class is the base class of all array types. La classe System.Array possède des propriétés permettant de déterminer le rang, la longueur et les limites inférieures et supérieures d’un tableau, ainsi que des méthodes permettant d’accéder, de trier, de rechercher, de copier et de créer des tableaux.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.

Ces types tableau sont dynamiques et n’ont pas de type statique correspondant défini dans la bibliothèque de classes de base.These array types are dynamic and do not have a corresponding static type defined in the base class library. Il est pratique de considérer chaque combinaison de type d’élément et de rang comme un type distinct de tableau.It is convenient to think of each combination of element type and rank as a distinct type of array. Par conséquent, un tableau unidimensionnel d’entiers constitue un type différent par rapport à un tableau unidimensionnel de types doubles.Therefore, a one-dimensional array of integers is of a different type than a one-dimensional array of double types. De même, un tableau à deux dimensions d’entiers constitue un type différent par rapport à un tableau unidimensionnel d’entiers.Similarly a two-dimensional array of integers is different from a one-dimensional array of integers. Les limites du tableau ne sont pas prises en compte lors de la comparaison des types.The bounds of the array are not considered when comparing types.

Comme le tableau ci-dessous l’indique, toute instance d’un tableau managé doit avoir un type d’élément, un rang et une limite inférieure spécifiques.As the following table shows, any instance of a managed array must be of a specific element type, rank, and lower bound.

Type tableau managéManaged array type Type d'élémentElement type RangRank Limite inférieureLower bound Notation de signatureSignature notation
ELEMENT_TYPE_ARRAYELEMENT_TYPE_ARRAY Spécifié par type.Specified by type. Spécifié par rang.Specified by rank. Spécifiée de manière facultative par des limites.Optionally specified by bounds. type [ n,m ]type [ n,m ]
ELEMENT_TYPE_CLASSELEMENT_TYPE_CLASS InconnuUnknown InconnuUnknown InconnuUnknown System.ArraySystem.Array
ELEMENT_TYPE_SZARRAYELEMENT_TYPE_SZARRAY Spécifié par type.Specified by type. 11 00 type [ n ]type [ n ]

Tableaux non managésUnmanaged Arrays

Les tableaux non managés sont soit des tableaux sécurisés de style COM, soit des tableaux de style C de longueur fixe ou variable.Unmanaged arrays are either COM-style safe arrays or C-style arrays with fixed or variable length. Les tableaux sécurisés sont des tableaux autodescriptifs qui comportent le type, le rang et les limites des données de tableau associées.Safe arrays are self-describing arrays that carry the type, rank, and bounds of the associated array data. Les tableaux de style C sont des tableaux typés unidimensionnels dont la limite inférieure fixe est 0.C-style arrays are one-dimensional typed arrays with a fixed lower bound of 0. La prise en charge par le service marshaling de ces deux types de tableaux est limitée.The marshaling service has limited support for both types of arrays.

Passage de paramètres de tableau au code .NETPassing Array Parameters to .NET Code

Les tableaux sécurisés et les tableaux de style C peuvent tous deux être passés à du code .NET à partir de code non managé soit comme tableau sécurisé, soit comme tableau de style 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. Le tableau suivant illustre la valeur de type non managé et le type importé.The following table shows the unmanaged type value and the imported type.

Type non managéUnmanaged type Type importéImported type
SafeArray( Type )SafeArray( Type ) ELEMENT_TYPE_SZARRAY < ConvertedType >ELEMENT_TYPE_SZARRAY < ConvertedType >

Rang = 1, limite inférieure = 0.Rank = 1, lower bound = 0. La taille n’est connue que si elle est fournie dans la signature managée.Size is known only if provided in the managed signature. Les tableaux sécurisés qui n’ont pas le rang = 1 ou la limite inférieure = 0 ne peuvent pas être marshalés en tant que 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 >

Rang = 1, limite inférieure = 0.Rank = 1, lower bound = 0. La taille n’est connue que si elle est fournie dans la signature managée.Size is known only if provided in the managed signature.

Tableaux sécurisésSafe Arrays

Quand un tableau sécurisé est importé à partir d’une bibliothèque de types vers un assembly .NET, le tableau est converti en tableau unidimensionnel de type connu (comme 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). Les mêmes règles de conversion de type qui s’appliquent aux paramètres sont également valables pour les éléments de tableau.The same type conversion rules that apply to parameters also apply to array elements. Par exemple, un tableau sécurisé de types BSTR devient un tableau managé de chaînes et un tableau sécurisé de variants devient un tableau managé d’objets.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. Le type d’élément SAFEARRAY est capturé à partir de la bibliothèque de types et enregistré dans la valeur SAFEARRAY de l’énumération UnmanagedType.The SAFEARRAY element type is captured from the type library and saved in the SAFEARRAY value of the UnmanagedType enumeration.

Étant donné que le rang et les limites du tableau sécurisé ne peuvent pas être déterminés à partir de la bibliothèque de types, le rang est considéré comme étant égal à 1 et la limite inférieure égale à 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. Le rang et les limites doivent être définis dans la signature managée produite par l’outil Tlbimp.exe (importateur de bibliothèques de types).The rank and bounds must be defined in the managed signature produced by the Type Library Importer (Tlbimp.exe). Si le rang passé à la méthode au moment de l’exécution est différent, une exception SafeArrayRankMismatchException est levée.If the rank passed to the method at run time differs, a SafeArrayRankMismatchException is thrown. Si le type du tableau passé au moment de l’exécution est différent, une exception SafeArrayTypeMismatchException est levée.If the type of the array passed at run time differs, a SafeArrayTypeMismatchException is thrown. L’exemple suivant montre des tableaux sécurisés dans du code managé et non managé.The following example shows safe arrays in managed and unmanaged code.

Signature non managéeUnmanaged signature

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

Signature managéeManaged 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);  

Les tableaux sécurisés multidimensionnels ou non limités par zéro peuvent être marshalés dans du code managé si la signature de méthode produite par Tlbimp.exe est modifiée pour indiquer un type d’élément ELEMENT_TYPE_ARRAY au lieu d’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. Vous pouvez également utiliser le commutateur /sysarray avec Tlbimp.exe pour importer tous les tableaux en tant qu’objets System.Array.Alternatively, you can use the /sysarray switch with Tlbimp.exe to import all arrays as System.Array objects. Pour les cas où le tableau passé se révèle être multidimensionnel, vous pouvez modifier le code MSIL (Microsoft Intermediate Language) produit par Tlimb.exe, puis le recompiler.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. Pour plus d’informations sur la manière de modifier du code MSIL, consultez Personnalisation des wrappers RCW.For details about how to modify MSIL code, see Customizing Runtime Callable Wrappers.

Tableaux de style CC-Style Arrays

Quand un tableau de style C est importé à partir d’une bibliothèque de types vers un assembly .NET, le tableau est converti en 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.

Le type d’élément de tableau est déterminé à partir de la bibliothèque de types et préservé lors de l’importation.The array element type is determined from the type library and preserved during the import. Les mêmes règles de conversion qui s’appliquent aux paramètres sont également valables pour les éléments de tableau.The same conversion rules that apply to parameters also apply to array elements. Par exemple, un tableau de types LPStr devient un tableau de types String.For example, an array of LPStr types becomes an array of String types. Tlbimp.exe capture le type d’élément de tableau et applique l’attribut MarshalAsAttribute au paramètre.Tlbimp.exe captures the array element type and applies the MarshalAsAttribute attribute to the parameter.

Le rang du tableau est considéré comme étant égal à 1.The array rank is assumed to equal 1. Si le rang est supérieur à 1, le tableau est marshalé en tant que tableau unidimensionnel en colonne.If the rank is greater than 1, the array is marshaled as a one-dimensional array in column-major order. La limite inférieure est toujours égale à 0.The lower bound always equals 0.

Des bibliothèques de types peuvent contenir des tableaux dont la longueur est fixe ou variable.Type libraries can contain arrays of fixed or variable length. Tlbimp.exe peut importer uniquement des tableaux dont la longueur est fixe à partir des bibliothèques de types, car les bibliothèques de types ne disposent pas des informations nécessaires pour marshaler des tableaux de longueur variable.Tlbimp.exe can import only fixed-length arrays from type libraries because type libraries lack the information needed to marshal variable-length arrays. Pour les tableaux de longueur fixe, la taille est importée à partir de la bibliothèque de types et capturée dans le MarshalAsAttribute qui est appliqué au paramètre.With fixed-length arrays, the size is imported from the type library and captured in the MarshalAsAttribute that is applied to the parameter.

Vous devez définir manuellement les bibliothèques de types contenant des tableaux de longueur variable comme le montre l’exemple suivant.You must manually define type libraries containing variable-length arrays, as shown in the following example.

Signature non managéeUnmanaged signature

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

Signature managéeManaged 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);  

Bien qu’il vous soit possible d’appliquer les attributs size_is ou length_is à un tableau dans la source IDL (Interface Definition Language) pour décrire la taille au client, le compilateur MIDL (Microsoft Interface Definition Language) ne propage pas ces informations à la bibliothèque de types.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. Sans connaissance de la taille, le service marshaling d’interopérabilité ne peut pas marshaler les éléments du tableau.Without knowing the size, the interop marshaling service cannot marshal the array elements. Par conséquent, les tableaux de longueur variable sont importés comme arguments de référence.Consequently, variable-length arrays are imported as reference arguments. Par exemple :For example:

Signature non managéeUnmanaged signature

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

Signature managéeManaged 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);   

Vous pouvez fournir la taille du tableau au marshaleur en éditant le code MSIL produit par Tlbimp.exe, puis en le recompilant.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. Pour plus d’informations sur la manière de modifier du code MSIL, consultez Personnalisation des wrappers RCW.For details about how to modify MSIL code, see Customizing Runtime Callable Wrappers. Pour indiquer le nombre d’éléments figurant dans le tableau, appliquez le type MarshalAsAttribute au paramètre de tableau de la définition de méthode managée en procédant de l’une des manières suivantes :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:

  • Identifiez un autre paramètre qui contient le nombre d’éléments figurant dans le tableau.Identify another parameter that contains the number of elements in the array. Les paramètres sont identifiés par position, le premier portant le numéro 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 );  
    
  • Définissez la taille du tableau comme constante.Define the size of the array as a constant. Par exemple :For example:

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

Quand il marshale des tableaux à partir du code non managé vers le code managé, le marshaleur vérifie l’attribut MarshalAsAttribute associé au paramètre pour déterminer la taille du tableau.When marshaling arrays from unmanaged code to managed code, the marshaler checks the MarshalAsAttribute associated with the parameter to determine the array size. Si la taille du tableau n’est pas spécifiée, seul un élément est marshalé.If the array size is not specified, only one element is marshaled.

Notes

L’attribut MarshalAsAttribute n’a aucun effet sur le marshaling de tableaux managés vers du code non managé.The MarshalAsAttribute has no effect on marshaling managed arrays to unmanaged code. Dans ce sens, la taille du tableau est déterminée par examen.In that direction, the array size is determined by examination. Il est impossible de marshaler un sous-ensemble d’un tableau managé.There is no way to marshal a subset of a managed array.

Le marshaleur d’interopérabilité utilise les méthodes CoTaskMemAlloc et CoTaskMemFree pour allouer et récupérer de la mémoire.The interop marshaler uses the CoTaskMemAlloc and CoTaskMemFree methods to allocate and retrieve memory. L’allocation de mémoire effectuée par le code non managé doit également utiliser ces méthodes.Memory allocation performed by unmanaged code must also use these methods.

Passage de tableaux à COMPassing Arrays to COM

Tous les types tableau managés peuvent être passés au code non managé à partir du code managé.All managed array types can be passed to unmanaged code from managed code. En fonction du type managé et des attributs qui lui sont appliqués, le tableau est accessible comme tableau sécurisé ou comme tableau de style C, comme le montre le tableau suivant.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.

Type tableau managéManaged array type Exporté commeExported as
ELEMENT_TYPE_SZARRAY < type >ELEMENT_TYPE_SZARRAY < type > UnmanagedType .SafeArray( type )UnmanagedType .SafeArray( type )

UnmanagedType.LPArrayUnmanagedType.LPArray

Type est fourni dans la signature.Type is provided in the signature. Le rang est toujours 1, la limite inférieure est toujours 0.Rank is always 1, lower bound is always 0. La taille est toujours connue au moment de l’exécution.Size is always known at run time.
ELEMENT_TYPE_ARRAY < type > < rang >[< limites >]ELEMENT_TYPE_ARRAY < type > < rank >[< bounds >] UnmanagedType.SafeArray( type )UnmanagedType.SafeArray( type )

UnmanagedType.LPArrayUnmanagedType.LPArray

Type, rang et limites sont fournis dans la signature.Type, rank, bounds are provided in the signature. La taille est toujours connue au moment de l’exécution.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, rang, limites et taille sont toujours connus au moment de l’exécution.Type, rank, bounds, and size are always known at run time.

Il existe une restriction dans OLE Automation concernant les tableaux de structures qui contiennent LPSTR ou LPWSTR.There is a limitation in OLE Automation relating to arrays of structures that contain LPSTR or LPWSTR. Par conséquent, les champs String doivent être marshalés comme UnmanagedType.BSTR.Therefore, String fields have to be marshaled as UnmanagedType.BSTR. Sinon, une exception est levée.Otherwise, an exception will be thrown.

ELEMENT_TYPE_SZARRAYELEMENT_TYPE_SZARRAY

Quand une méthode contenant un paramètre ELEMENT_TYPE_SZARRAY (tableau unidimensionnel) est exportée à partir d’un assembly .NET vers une bibliothèque de types, le paramètre de tableau est converti en un SAFEARRAY d’un type donné.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. Les mêmes règles de conversion s’appliquent aux types d’éléments de tableau.The same conversion rules apply to the array element types. Le contenu du tableau managé est automatiquement copié à partir de la mémoire managée dans le SAFEARRAY.The contents of the managed array are automatically copied from managed memory into the SAFEARRAY. Par exemple :For example:

Signature managéeManaged signature

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

Signature non managéeUnmanaged signature

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

Le rang des tableaux sécurisés est toujours 1 et la limite inférieure est toujours 0.The rank of the safe arrays is always 1 and the lower bound is always 0. La taille est déterminée au moment de l’exécution par la taille du tableau managé qui est passé.The size is determined at run time by the size of the managed array being passed.

Le tableau peut également être marshalé en tant que tableau de style C en utilisant l’attribut MarshalAsAttribute.The array can also be marshaled as a C-style array by using the MarshalAsAttribute attribute. Par exemple :For example:

Signature managéeManaged 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 );  

Signature non managéeUnmanaged signature

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

Bien que le marshaleur possède les informations de longueur nécessaires pour marshaler le tableau, la longueur du tableau est généralement passée comme argument séparé afin de l’envoyer à l’appelé.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

Quand une méthode contenant un paramètre ELEMENT_TYPE_ARRAY est exportée à partir d’un assembly .NET vers une bibliothèque de types, le paramètre de tableau est converti en un SAFEARRAY d’un type donné.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. Le contenu du tableau managé est automatiquement copié à partir de la mémoire managée dans le SAFEARRAY.The contents of the managed array are automatically copied from managed memory into the SAFEARRAY. Par exemple :For example:

Signature managéeManaged signature

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

Signature non managéeUnmanaged signature

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

Le rang, la taille et les limites des tableaux sécurisés sont déterminés au moment de l’exécution par les caractéristiques du tableau managé.The rank, size, and bounds of the safe arrays are determined at run time by the characteristics of the managed array.

Le tableau peut également être marshalé en tant que tableau de style C en appliquant l’attribut MarshalAsAttribute.The array can also be marshaled as a C-style array by applying the MarshalAsAttribute attribute. Par exemple :For example:

Signature managéeManaged 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 );  

Signature non managéeUnmanaged signature

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

Les tableaux imbriqués ne peuvent pas être marshalés.Nested arrays cannot be marshaled. Par exemple, la signature suivante génère une erreur quand elle est exportée à l’aide de l’outil Tlbexp.exe (exportateur de bibliothèques de types).For example, the following signature generates an error when exported with the Type Library Exporter (Tlbexp.exe).

Signature managéeManaged signature

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

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

Quand une méthode contenant un paramètre System.Array est exportée à partir d’un assembly .NET vers une bibliothèque de types, le paramètre de tableau est converti en une interface _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. Le contenu du tableau managé est accessible uniquement par les méthodes et les propriétés de l’interface _Array.The contents of the managed array are accessible only through the methods and properties of the _Array interface. La méthode System.Array peut également être marshalée comme un SAFEARRAY à l’aide de l’attribut MarshalAsAttribute.System.Array can also be marshaled as a SAFEARRAY by using the MarshalAsAttribute attribute. Quand ils sont marshalés comme tableau sécurisé, les éléments du tableau sont marshalés comme variants.When marshaled as a safe array, the array elements are marshaled as variants. Par exemple :For example:

Signature managéeManaged 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 );  

Signature non managéeUnmanaged signature

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

Tableaux à l’intérieur de structuresArrays within Structures

Les structures non managées peuvent contenir des tableaux incorporés.Unmanaged structures can contain embedded arrays. Par défaut, ces champs de tableau incorporés sont marshalés en tant que SAFEARRAY.By default, these embedded array fields are marshaled as a SAFEARRAY. Dans l’exemple suivant, s1 est un tableau incorporé qui est alloué directement au sein de la structure elle-même.In the following example, s1 is an embedded array that is allocated directly within the structure itself.

Représentation non managéeUnmanaged representation

struct MyStruct {  
    short s1[128];  
}  

Les tableaux peuvent être marshalés comme UnmanagedType, ce qui exige que vous définissiez le champ MarshalAsAttribute.Arrays can be marshaled as UnmanagedType, which requires you to set the MarshalAsAttribute field. La taille peut être définie uniquement comme constante.The size can be set only as a constant. Le code suivant montre la définition managée correspondante de 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;  
}  

Voir aussiSee also