Condividi tramite


Puntatori univoci

Nei programmi C più puntatori possono contenere l'indirizzo dei dati. Si dice che i puntatori creino un alias per i dati. Gli alias vengono creati anche quando i puntatori puntano alle variabili dichiarate. Il frammento di codice seguente illustra entrambi questi metodi di 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;

In un programma C tipico è possibile specificare un albero binario usando la definizione seguente:

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

TREETYPE * troot;

Più puntatori possono accedere al contenuto di un nodo della struttura ad albero. Questa operazione è in genere adatta alle applicazioni non stribute. Tuttavia, questo stile di programmazione genera codice di supporto RPC più complesso. Gli stub client e server richiedono il codice aggiuntivo per gestire i dati e i puntatori. Il codice stub sottostante deve risolvere i vari puntatori agli indirizzi e determinare quale copia dei dati rappresenta la versione più recente.

La quantità di elaborazione può essere ridotta se si garantisce che il puntatore sia l'unico modo in cui l'applicazione può accedere a tale area di memoria. Il puntatore può comunque avere molte delle funzionalità di un puntatore C. Ad esempio, può cambiare tra valori Null e non Null o rimanere invariati. Questa condizione è illustrata nell'esempio seguente. Il puntatore è Null prima della chiamata e punta a una stringa valida dopo la chiamata:

cambio di puntatore tra valori Null e non Null

Per impostazione predefinita, il compilatore MIDL applica l'attributo puntatore [ unique] a tutti i puntatori che non sono parametri. Questa impostazione predefinita può essere modificata con l'attributo [ pointer_default].

Un puntatore univoco presenta le caratteristiche seguenti:

  • Può avere il valore Null.
  • Può passare da Null a non Null durante la chiamata. Quando il valore diventa diverso da Null, la nuova memoria viene allocata in caso di restituzione.
  • Può passare da non Null a Null durante la chiamata. Quando il valore viene modificato in NULL, l'applicazione è responsabile della liberazione della memoria.
  • Il valore può passare da un valore diverso da Null a un altro.
  • Non è possibile accedere allo spazio di archiviazione a cui punta un puntatore univoco da qualsiasi altro puntatore o nome nell'operazione.
  • I dati restituiti vengono scritti nella risorsa di archiviazione esistente se il puntatore non ha il valore Null.

Nell'esempio seguente viene illustrato come definire un puntatore univoco.

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

In questo esempio, il parametro ach è un puntatore univoco ai dati di tipo carattere inviati a un server da elaborare con la routine RemoteFn.