Pointeurs uniques

Dans les programmes C, plusieurs pointeurs peuvent contenir l’adresse des données. Les pointeurs sont dits de créer un alias pour les données. Des alias sont également créés lorsque des pointeurs pointent vers des variables déclarées. Le fragment de code suivant illustre ces deux méthodes d’aliasing :

int iAnInteger=50;

// The next statement makes ipAnIntegerPointer an
// alias for iAnInteger.
int *ipAnIntegerPointer = &iAnInteger;

// This statement creates an alias for ipAnIntegerPointer.
int *ipAnotherIntegerPointer = ipAnIntegerPointer;

Dans un programme C classique, vous pouvez spécifier une arborescence binaire à l’aide de la définition suivante :

typedef struct _treetype 
{
    long               lValue;
    struct _treetype * left;
    struct _treetype * right;
} TREETYPE;

TREETYPE * troot;

Plusieurs pointeurs peuvent accéder au contenu d’un nœud d’arborescence. Cela est généralement correct pour les applications non distribuées. Toutefois, ce style de programmation génère un code de prise en charge RPC plus complexe. Les stubs client et serveur nécessitent le code supplémentaire pour gérer les données et les pointeurs. Le code stub sous-jacent doit résoudre les différents pointeurs vers les adresses et déterminer quelle copie des données représente la version la plus récente.

La quantité de traitement peut être réduite si vous garantissez que votre pointeur est le seul moyen pour l’application d’accéder à cette zone de mémoire. Le pointeur peut toujours avoir la plupart des fonctionnalités d’un pointeur C. Par exemple, il peut changer entre des valeurs null et non null ou rester identique. L'exemple suivant illustre ce comportement. Le pointeur est null avant l’appel et pointe vers une chaîne valide après l’appel :

changement de pointeur entre des valeurs null et non null

Par défaut, le compilateur MIDL applique l’attribut de pointeur [ unique] à tous les pointeurs qui ne sont pas des paramètres. Ce paramètre par défaut peut être modifié avec l’attribut [ pointer_default].

Un pointeur unique présente les caractéristiques suivantes :

  • Il peut avoir la valeur null.
  • Il peut passer de null à non null pendant l’appel. Lorsque la valeur devient non null, une nouvelle mémoire est allouée au retour.
  • Il peut passer de non null à null pendant l’appel. Lorsque la valeur passe à NULL, l’application est responsable de libérer la mémoire.
  • La valeur peut passer d’une valeur non null à une autre.
  • Le stockage vers lequel pointe un pointeur unique n’est accessible à aucun autre pointeur ou nom dans l’opération.
  • Les données de retour sont écrites dans le stockage existant si le pointeur n’a pas la valeur null.

L’exemple suivant montre comment définir un pointeur unique.

/* IDL file */
[ 
  uuid(ba209999-0c6c-11d2-97cf-00c04f8eea45),
  version(1.0)
]
interface RefPtrInterface
{
  void RemoteFn([in, unique] char *ach);
}

Dans cet exemple, le paramètre ach est un pointeur unique vers les données de caractères envoyées à un serveur pour être traitées avec la routine RemoteFn.