Поделиться через


Уникальные указатели

В программах 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 и не 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.