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


Массивы MIDL

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

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

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

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

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

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

Массив называется "соответствующим", если верхняя граница любого измерения определяется во время выполнения. (Во время выполнения можно определить только верхние границы.) Чтобы определить верхнюю границу, объявление массива должно содержать атрибут 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..*] 
);

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

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

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

Например, тип RECT_TYPE можно определить как двухмерный массив, а переменная прямоугольника может быть определена как массив 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], особенно если массив связан с значениями [in], [in], [length_is], или [last_is]. Клиентское приложение также должно инициализировать все элементы массива перед вызовом. Прежде чем вернуться клиенту, серверное приложение должно убедиться, что все элементы массива в передаваемой точке диапазона в допустимое хранилище.

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

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

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

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

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

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