Punteros únicos
En los programas de C, más de un puntero puede contener la dirección de los datos. Se dice que los punteros crean un alias para los datos. Los alias también se crean cuando los punteros apuntan a variables declaradas. En el fragmento de código siguiente se muestran ambos métodos de alias:
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;
En un programa de C típico, puede especificar un árbol binario con la siguiente definición:
typedef struct _treetype
{
long lValue;
struct _treetype * left;
struct _treetype * right;
} TREETYPE;
TREETYPE * troot;
Más de un puntero puede acceder al contenido de un nodo de árbol. Esto suele ser adecuado para aplicaciones no distribuidas. Sin embargo, este estilo de programación genera código de compatibilidad con RPC más complicado. Los códigos auxiliares de cliente y servidor requieren el código adicional para administrar los datos y los punteros. El código auxiliar subyacente debe resolver los distintos punteros a las direcciones y determinar qué copia de los datos representa la versión más reciente.
La cantidad de procesamiento se puede reducir si garantiza que el puntero es la única manera en que la aplicación puede acceder a ese área de memoria. El puntero todavía puede tener muchas de las características de un puntero de C. Por ejemplo, puede cambiar entre valores NULL y no NULL o permanecer igual. Esto se ilustra en el siguiente ejemplo: El puntero es null antes de la llamada y apunta a una cadena válida después de la llamada:
De forma predeterminada, el compilador MIDL aplica el atributo de puntero [ unique] a todos los punteros que no son parámetros. Esta configuración predeterminada se puede cambiar con el atributo [ pointer_default].
Un puntero único tiene las siguientes características:
- Puede tener el valor NULL.
- Puede cambiar de null a no null durante la llamada. Cuando el valor cambia a distinto de NULL, se asigna nueva memoria a la devolución.
- Puede cambiar de distinto de NULL a NULL durante la llamada. Cuando el valor cambia a NULL, la aplicación es responsable de liberar la memoria.
- El valor puede cambiar de un valor distinto de NULL a otro.
- El almacenamiento al que apunta un puntero único no puede tener acceso ningún otro puntero o nombre en la operación.
- Los datos devueltos se escriben en el almacenamiento existente si el puntero no tiene el valor NULL.
En el ejemplo siguiente se muestra cómo definir un puntero único.
/* IDL file */
[
uuid(ba209999-0c6c-11d2-97cf-00c04f8eea45),
version(1.0)
]
interface RefPtrInterface
{
void RemoteFn([in, unique] char *ach);
}
En este ejemplo, el parámetro ach es un puntero único a los datos de caracteres que se envían a un servidor que se van a procesar con la rutina RemoteFn.