copie et épinglageCopying and Pinning

Lors du marshaling des données, le marshaleur d’interopérabilité peut copier ou épingler les données qui sont marshalées.When marshaling data, the interop marshaler can copy or pin the data being marshaled. La copie des données déplace une copie des données d’un emplacement de mémoire vers un autre emplacement de mémoire.Copying the data places a copy of data from one memory location in another memory location. L’illustration suivante montre les différences entre la copie d’un type valeur et la copie d’un type passé par référence à partir de la mémoire managée vers la mémoire non managée.The following illustration shows the differences between copying a value type and copying a type passed by reference from managed to unmanaged memory.

Diagramme illustrant la façon dont sont copiés les types référence et valeur.

Des arguments de méthode passés par valeur sont marshalés vers le code non managé en tant que valeurs sur la pile.Method arguments passed by value are marshaled to unmanaged code as values on the stack. Le processus de copie est direct.The copying process is direct. Les arguments passés par référence sont passés comme pointeurs sur la pile.Arguments passed by reference are passed as pointers on the stack. Les types référence sont également passés par valeur et par référence.Reference types are also passed by value and by reference. Comme le montre l’illustration suivante, les types référence passés en valeur sont soit copiés, soit épinglés :As the following illustration shows, reference types passed by value are either copied or pinned:

Diagramme illustrant des types référence passés en valeur et en référence.

L’épinglage verrouille temporairement les données dans leur emplacement de mémoire actuel, évitant ainsi qu’elles ne soient déplacées par le garbage collector du common language runtime.Pinning temporarily locks the data in its current memory location, thus keeping it from being relocated by the common language runtime's garbage collector. Le marshaleur épingle des données pour réduire la charge mémoire imposée par la copie et pour améliorer les performances.The marshaler pins data to reduce the overhead of copying and enhance performance. Le type des données détermine si celles-ci sont copiées ou épinglées lors du processus de marshaling.The type of the data determines whether it is copied or pinned during the marshaling process. L’épinglage se fait automatiquement pendant le marshaling pour les objets tels que String. Cependant, vous pouvez également épingler manuellement la mémoire à l’aide de la classe GCHandle.Pinning is automatically performed during marshaling for objects such as String, however you can also manually pin memory using the GCHandle class.

Classes blittables mises en formeFormatted Blittable Classes

Les classes blittables mises en forme ont une disposition fixe (mise en forme) et une représentation commune des données en mémoire managée et non managée.Formatted blittable classes have fixed layout (formatted) and common data representation in both managed and unmanaged memory. Quand ces types nécessitent d’être marshalés, un pointeur vers l’objet dans le tas est passé directement à l’appelé.When these types require marshaling, a pointer to the object in the heap is passed to the callee directly. L’appelé peut changer le contenu de l’emplacement de mémoire référencé par le pointeur.The callee can change the contents of the memory location being referenced by the pointer.

Notes

L’appelé peut changer le contenu de la mémoire si le paramètre est marqué en sortie ou en entrée/sortie. En revanche, l’appelé doit éviter de changer le contenu quand le paramètre est défini pour marshaler en entrée, qui est le paramètre par défaut pour les types blittables mis en forme.The callee can change the memory contents if the parameter is marked Out or In/Out. In contrast, the callee should avoid changing the contents when the parameter is set to marshal as In, which is the default for formatted blittable types. La modification d’un objet en entrée génère des problèmes quand la même classe est exportée vers une bibliothèque de types et utilisée pour effectuer des appels entre cloisonnements.Modifying an In object generates problems when the same class is exported to a type library and used to make cross-apartment calls.

Classes non blittables mises en formeFormatted Non-Blittable Classes

Les classes non blittables mises en forme ont une disposition fixe (mise en forme), mais la représentation des données est différente en mémoire managée et non managée.Formatted non-blittable classes have fixed layout (formatted) but the data representation is different in managed and unmanaged memory. Les données peuvent nécessiter des transformations dans les situations suivantes :The data can require transformation under the following conditions:

  • Si une classe non blittable est marshalée par valeur, l’appelé reçoit un pointeur vers une copie de la structure de données.If a non-blittable class is marshaled by value, the callee receives a pointer to a copy of the data structure.

  • Si une classe non blittable est marshalée par référence, l’appelé reçoit un pointeur vers un pointeur vers une copie de la structure de données.If a non-blittable class is marshaled by reference, the callee receives a pointer to a pointer to a copy of the data structure.

  • Si l’attribut InAttribute est défini, cette copie est toujours initialisée avec l’état de l’instance, en marshalant si nécessaire.If the InAttribute attribute is set, this copy is always initialized with the instance's state, marshaling as necessary.

  • Si l’attribut OutAttribute est défini, l’état est toujours recopié dans l’instance au retour, en marshalant si nécessaire.If the OutAttribute attribute is set, the state is always copied back to the instance on return, marshaling as necessary.

  • Si les deux attributs InAttribute et OutAttribute sont définis, les deux copies sont requises.If both InAttribute and OutAttribute are set, both copies are required. Si l’un des attributs est omis, le marshaleur peut optimiser en éliminant l’une des copies.If either attribute is omitted, the marshaler can optimize by eliminating either copy.

Types référenceReference Types

Les types référence peuvent être passés par valeur ou par référence.Reference types can be passed by value or by reference. Quand ils sont passés par valeur, un pointeur vers le type est passé sur la pile.When they are passed by value, a pointer to the type is passed on the stack. Quand ils sont passés par référence, un pointeur vers un pointeur vers le type est passé sur la pile.When passed by reference, a pointer to a pointer to the type is passed on the stack.

Les types référence possèdent le comportement conditionnel suivant :Reference types have the following conditional behavior:

  • Si un type référence est passé par valeur et possède des membres de types non blittables, les types sont convertis deux fois :If a reference type is passed by value and it has members of non-blittable types, the types are converted twice:

    • Quand un argument est passé vers le côté non managé.When an argument is passed to the unmanaged side.

    • Lors du retour de l’appel.On return from the call.

    Pour éviter copie et conversion inutiles, ces types sont marshalés en tant que paramètres en entrée.To avoid unnecessarily copying and conversion, these types are marshaled as In parameters. Vous devez appliquer explicitement les attributs InAttribute et OutAttribute à un argument pour que l’appelant voie les changements effectués par l’appelé.You must explicitly apply the InAttribute and OutAttribute attributes to an argument for the caller to see changes made by the callee.

  • Si un type référence est passé par valeur et ne possède que des membres de types blittables, ce type peut être épinglé lors du marshaling et tout changement apporté par l’appelé aux membres du type est vu par l’appelant.If a reference type is passed by value and it has only members of blittable types, it can be pinned during marshaling and any changes made to the members of the type by the callee are seen by the caller. Appliquez les attributs InAttribute et OutAttribute explicitement si vous voulez ce comportement.Apply InAttribute and OutAttribute explicitly if you want this behavior. Sans ces attributs directionnels, le marshaleur d’interopérabilité n’exporte pas d’informations directionnelles vers la bibliothèque de types (il exporte en entrée, ce qui est le paramètre par défaut). Cela peut poser des problèmes lors du marshaling entre cloisonnements COM.Without these directional attributes, the interop marshaler does not export directional information to the type library (it exports as In, which is the default) and this can cause problems with COM cross-apartment marshaling.

  • Si un type référence est passé par référence, il est marshalé en entrée/sortie par défaut.If a reference type is passed by reference, it will be marshaled as In/Out by default.

System.String et System.Text.StringBuilderSystem.String and System.Text.StringBuilder

Quand des données sont marshalées vers du code non managé par valeur ou par référence, le marshaleur copie généralement les données vers une mémoire tampon secondaire (en convertissant éventuellement des jeux de caractères lors de la copie) et passe une référence à la mémoire tampon à l’appelé.When data is marshaled to unmanaged code by value or by reference, the marshaler typically copies the data to a secondary buffer (possibly converting character sets during the copy) and passes a reference to the buffer to the callee. Sauf si la référence est un BSTR alloué avec SysAllocString, la référence est toujours allouée avec CoTaskMemAlloc.Unless the reference is a BSTR allocated with SysAllocString, the reference is always allocated with CoTaskMemAlloc.

Par souci d’optimisation quand l’un ou l’autre type de chaîne est marshalé par valeur (notamment comme chaîne de caractères Unicode), le marshaleur passe à l’appelé un pointeur direct vers des chaînes managées dans la mémoire tampon Unicode interne au lieu de le copier dans une nouvelle mémoire tampon.As an optimization when either string type is marshaled by value (such as a Unicode character string), the marshaler passes the callee a direct pointer to managed strings in the internal Unicode buffer instead of copying it to a new buffer.

Attention

Quand une chaîne est passée par valeur, l’appelé ne doit jamais changer la référence passée par le marshaleur.When a string is passed by value, the callee must never alter the reference passed by the marshaler. Sinon, il risque d’endommager le tas managé.Doing so can corrupt the managed heap.

Quand System.String est passé par référence, le marshaleur copie le contenu de la chaîne dans une mémoire tampon secondaire avant d’effectuer l’appel.When a System.String is passed by reference, the marshaler copies the contents the string to a secondary buffer before making the call. Il copie ensuite le contenu de la mémoire tampon dans une nouvelle chaîne au retour de l’appel.It then copies the contents of the buffer into a new string on return from the call. Cette technique garantit que la chaîne managée non modifiable demeure inchangée.This technique ensures that the immutable managed string remains unaltered.

Quand System.Text.StringBuilder est passé par valeur, le marshaleur passe une référence à la mémoire tampon interne de StringBuilder directement à l’appelant.When a System.Text.StringBuilder is passed by value, the marshaler passes a reference to the internal buffer of the StringBuilder directly to the caller. L’appelant et l’appelé doivent s’entendre sur la taille de la mémoire tampon.The caller and callee must agree on the size of the buffer. L’appelant est chargé de créer un StringBuilder de longueur adéquate.The caller is responsible for creating a StringBuilder of adequate length. L’appelé doit prendre les précautions nécessaires pour garantir le non-débordement de la mémoire tampon.The callee must take the necessary precautions to ensure that the buffer is not overrun. StringBuilder fait exception à la règle qui veut que les types référence passés par valeur sont passés comme paramètres en entrée par défaut.StringBuilder is an exception to the rule that reference types passed by value are passed as In parameters by default. Il est toujours passé comme paramètre en entrée/sortie.It is always passed as In/Out.

Voir aussiSee also