size_is - атрибут
Используйте атрибут [size_is], чтобы указать размер памяти в элементах, выделенных для указателей размера, указателей размера для указателей размера и одномерных или многомерных массивов.
[ size_is(limited-expression-list) ]
Параметры
-
limited-expression-list
-
Задает одно или несколько выражений языка C. Каждое выражение вычисляется как неотрицательное целое число, представляющее объем памяти, выделенный для указателя размера или массива. В случае массива задает одно выражение, представляющее размер выделения в элементах первого измерения этого массива. Компилятор MIDL поддерживает условные выражения, логические выражения, реляционные выражения и арифметические выражения. MIDL не допускает вызовы функций в выражениях и не допускает операторы приращения и декремента. Используйте запятые в качестве заполнителей для неявных параметров или для разделения нескольких выражений.
Комментарии
Если вы используете атрибут [size_is] для выделения памяти для многомерного массива и используете нотацию массива [], помните, что во время выполнения динамически можно определить только первое измерение многомерного массива. Другие измерения должны быть заданы статически. Дополнительные сведения об использовании атрибута [size_is] с несколькими уровнями указателей, чтобы позволить серверу возвращать клиенту массив данных динамического размера, как показано в примере Proc7, см. в разделе Несколько уровней указателей.
Вы можете использовать [size_is] или max_is (но не оба в одном списке атрибутов), чтобы указать размер массива, верхние границы которого определяются во время выполнения. Обратите внимание, что атрибут [size_is] нельзя использовать в фиксированных измерениях массива. Атрибут [max_is] задает максимальный допустимый индекс массива. В результате указание [size_is(n)] эквивалентно указанию [max_is(n-1)].
Параметр массива [ in] или [in, out] с атрибутом [ string] не должен иметь атрибут [size_is] или [max_is]. В этом случае размер выделения определяется из признака конца NULL входной строки. Все остальные соответствующие массивы с атрибутом [string] должны иметь атрибут [size_is] или [max_is].
Хотя использовать атрибут [size_is] с константой является законным, это неэффективно и ненужно. Например, используйте массив фиксированного размера:
HRESULT Proc3([in] short Arr[MAX_SIZE]);
вместо
// legal but marshaling code is much slower
HRESULT Proc3([in size_is(MAX_SIZE)] short Arr[] );
Атрибуты [size_is] и [length_is] можно использовать вместе. В этом случае атрибут [size_is] управляет объемом памяти, выделенной для данных. Атрибут [length_is] указывает, сколько элементов передается. Объем памяти, указанный атрибутами [size_is] и [length_is], не должен совпадать. Например, клиент может передать параметр [in,out] на сервер и указать выделение большого объема памяти с помощью [size_is], даже если он указывает небольшое количество элементов данных, передаваемых с помощью [length_is]. Это позволяет серверу заполнять массив большими данными, чем он получил, которые затем он может отправить обратно клиенту.
Как правило, не рекомендуется указывать оба параметра [size_is] и [length_is] в параметрах [in] или [out]. В обоих случаях [size_is] управляет выделением памяти. Приложение может использовать [size_is] для выделения большего количества элементов массива, чем передается (как указано в [length_is]). Однако это было бы неэффективно. Кроме того, было бы неэффективно указывать одинаковые значения для [size_is] и [length_is]. Это создаст дополнительные издержки во время маршалинга параметров. Если значения [size_is] и [length_is] всегда одинаковы, опустите атрибут [length_is].
Примеры
HRESULT Proc1(
[in] short m;
[in, size_is(m)] short a[]); // If m = 10, a[10]
HRESULT Proc2(
[in] short m;
[in, size_is(m)] short b[][20]); // If m = 10, b[10][20]
HRESULT Proc3(
[in] short m;
[size_is(m)] short * pshort); /* Specifies a pointer
to an m-sized block of shorts */
HRESULT Proc4(
[in] short m;
[size_is( , m)] short ** ppshort); /* Specifies a pointer
to a pointer to an m-sized
block of shorts */
HRESULT Proc5(
[in] short m;
[size_is(m ,)] short ** ppshort); /* Specifies an
m-sized block of pointers
to shorts */
HRESULT Proc6(
[in] short m;
[in] short n;
[size_is(m,n)] short ** ppshort); /* Specifies a pointer to an
m-sized block of pointers, each
of which points to an n-sized
block of shorts. m associates with
the pointer closeest to the identifer
it decorates. n associates with rest.*/
HRESULT Proc7(
[out] long * pSize,
[out, size_is( , *pSize)] my_type ** ppMyType); /* Specifies a pointer
to a sized pointer,
which points to a block
of my_types, whose size is
unknown when the stub
calls the server. */
См. также раздел