Уникальные указатели
В программах C несколько указателей могут содержать адрес данных. Говорят, что указатели создают псевдоним для данных. Псевдонимы также создаются при указателях на объявленные переменные. Следующий фрагмент кода иллюстрирует оба этих метода псевдонима:
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;
В обычной программе C можно указать двоичное дерево с помощью следующего определения:
typedef struct _treetype
{
long lValue;
struct _treetype * left;
struct _treetype * right;
} TREETYPE;
TREETYPE * troot;
Несколько указателей могут получить доступ к содержимому узла дерева. Как правило, это хорошо для нераспровержанных приложений. Однако этот стиль программирования создает более сложный код поддержки RPC. Заглушки клиента и сервера требуют дополнительного кода для управления данными и указателями. Базовый код заглушки должен разрешать различные указатели на адреса и определять, какая копия данных представляет самую последнюю версию.
Объем обработки может быть сокращен, если вы гарантируете, что указатель является единственным способом, которым приложение может получить доступ к этой области памяти. Указатель по-прежнему может иметь множество функций указателя C. Например, он может измениться между null и незначениями null или оставаться неизменными. В следующем примере показано это. Указатель null перед вызовом и указывает на допустимую строку после вызова:
По умолчанию компилятор MIDL применяет атрибут указателя [ уникальный] ко всем указателям, которые не являются параметрами. Этот параметр по умолчанию можно изменить с помощью атрибута [ pointer_default] .
Уникальный указатель имеет следующие характеристики:
- Он может иметь значение null.
- Он может измениться с null наnull во время вызова. Если значение изменяется наnull, новая память выделяется при возврате.
- Он может измениться сnull на null во время вызова. Когда значение изменяется на NULL, приложение отвечает за освобождение памяти.
- Значение может измениться с одного значения, отличного отnull, на другое.
- Хранилище, к которому указывает уникальный указатель, к которому не удается получить доступ с помощью любого другого указателя или имени в операции.
- Возвращаемые данные записываются в существующее хранилище, если указатель не имеет значения null.
В следующем примере показано, как определить уникальный указатель.
/* IDL file */
[
uuid(ba209999-0c6c-11d2-97cf-00c04f8eea45),
version(1.0)
]
interface RefPtrInterface
{
void RemoteFn([in, unique] char *ach);
}
В этом примере параметр ach является уникальным указателем на символьные данные, которые отправляются на сервер для обработки с помощью подпрограммы RemoteFn.