Массивы MIDL

Деклараторы массива отображаются в тексте интерфейса IDL-файла как один из следующих:

  • Часть общего объявления
  • Член структуры или декларатора объединения
  • Параметр для удаленного вызова процедуры

Границы каждого измерения массива выражаются в отдельной паре квадратных скобок. Выражение, результатом которого является n , означает нижнюю границу, равную нулю, и верхнюю границу n – 1. Если квадратные скобки пусты или содержат одну звездочку (*), нижняя граница равна нулю, а верхняя граница определяется во время выполнения.

Массив также может содержать два значения, разделенные многоточием, которые представляют нижнюю и верхнюю границы массива, как в [нижнем...верхний]. Для Microsoft RPC требуется нижняя граница, равная нулю. Компилятор MIDL не распознает конструкции, указывающие ненулевые нижние границы.

Массивы можно связать с атрибутами полей size_is, max_is, length_is, first_is и last_is , чтобы указать размер массива или части массива, содержащего допустимые данные. Эти атрибуты поля определяют параметр, поле структуры или константу, задающую измерение массива или индекс.

Массив должен быть связан с идентификатором, заданным атрибутом field следующим образом: если массив является параметром, идентификатор также должен быть параметром для той же функции; Если массив является полем структуры, идентификатор должен быть другим полем структуры той же структуры.

Массив называется "соответствующим", если верхняя граница любого измерения определяется во время выполнения. (Во время выполнения можно определить только верхние границы.) Чтобы определить верхнюю границу, объявление массива должно содержать атрибут size_is или max_is .

Массив называется "переменным", когда его границы определяются во время компиляции, но диапазон передаваемых элементов определяется во время выполнения. Чтобы определить диапазон передаваемых элементов, объявление массива должно содержать атрибут length_is, first_is или last_is .

Соответствующий изменяющийся массив (также называемый "открытым") — это массив, верхняя граница которого и диапазон передаваемых элементов определяются во время выполнения. Не более одного соответствующего или соответствующего переменного массива можно вложить в структуру C и должен быть последним элементом структуры. В отличие от этого, несоотносимые массивы могут возникать в любой точке структуры.

Примеры

/* IDL file interface body */ 
#define MAX_INDEX 10 
 
typedef char  ATYPE[MAX_INDEX]; 
typedef short BTYPE[];        // Equivalent to [*]; 
typedef long  CTYPE[*][10];   // [][10] 
typedef float DTYPE[0..10];   // Equivalent to [11] 
typedef float ETYPE[0..(MAX_INDEX)];  
 
typedef struct 
{ 
    unsigned short size; 
    unsigned short length; 
    [size_is(size), length_is(length)] char string[*]; 
} counted_string; 
 
HRESULT MyFunction( 
     [in, out] short * pSize,  
     [in, out, string, size_is(*pSize)] char a[0..*] 
);

Дополнительные сведения см. в разделе Массивы и указатели.

Многомерные массивы

Пользователь может объявлять типы, которые являются массивами, а затем объявлять массивы объектов таких типов. Семантика m-мерных массивов типов n-мерных массивов аналогична семантике m+n-мерных массивов.

Например, тип RECT_TYPE можно определить как двумерный массив, а переменную rect — как массив RECT_TYPE. Это эквивалентно equivalent_rect трехмерного массива:

typedef short int RECT_TYPE[10][20]; 
RECT_TYPE rect[15]; 
short int equivalent_rect[15][10][20];  // ~RECT_TYPE rect[15]

Microsoft RPC ориентирован на C. В соответствии с соглашениями языка C во время выполнения можно определить только первое измерение многомерного массива. Взаимодействие с массивами IDL DCE, поддерживающими другие языки, ограничено:

  • Многомерные массивы с константами (определяемые во время компиляции) границами.
  • Многомерные массивы со всеми константными границами, кроме первого измерения. Верхняя граница и диапазон передаваемых элементов первого измерения зависят от среды выполнения.
  • Любые одномерные массивы с нижней границей, равной нулю.

Если атрибут [string] используется в многомерных массивах, он применяется к крайнему правому массиву.

Массивы указателей

Указатели ссылок должны указывать на допустимые данные. Клиентское приложение должно выделить всю память для массива ссылочных указателей [in] или [in,out], особенно если массив связан со значениями [in], [in,out], [length_is] или [last_is]. Клиентское приложение также должно инициализировать все элементы массива перед вызовом . Прежде чем вернуться клиенту, серверное приложение должно убедиться, что все элементы массива в передаваемой точке диапазона передаются в допустимое хранилище.

На стороне сервера заглушка выделяет хранилище для всех элементов массива, независимо от значения [length_is] или [last_is] во время вызова. Эта функция может повлиять на производительность приложения.

На массивы уникальных указателей не накладываются никакие ограничения. Как на клиенте, так и на сервере хранилище выделяется для пустых указателей. Если указатели не являются пустыми, данные помещаются в предварительно выделяемое хранилище.

Необязательный декларатор указателя может предшествовать декларатору массива.

Если внедренные ссылочные указатели являются параметрами только [out], код диспетчера сервера должен назначать допустимые значения массиву ссылочных указателей. Пример:

typedef [ref] short * ARefPointer;
typedef ARefPointer ArrayOfRef[10];
HRESULT proc1( [out] ArrayOfRef Parameter );

Созданные заглушки выделяют массив и присваивают значения NULL всем указателям, внедренным в массив.