Уникальные указатели
В программах 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 перед вызовом и указывает на допустимую строку после вызова:
По умолчанию компилятор MIDL применяет атрибут [ unique] указателя ко всем указателям, которые не являются параметрами. Этот параметр по умолчанию можно изменить с помощью атрибута [ pointer_default].
Уникальный указатель имеет следующие характеристики:
- Он может иметь значение 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.