arrays

typedef [ [type-attr-list] ] type-specifier [pointer-decl] array-declarator;

typedef
[ [type-attr-list] ] struct [ tag ] {
    [ [ field-attribute-list ] ] type-specifier [pointer-decl] array-declarator;
    ...
}
typedef
[ [type-attr-list] ] union [ tag ] {
    [ case (
limited-expression [ , ... ] ) ]
        
[ [ field_attribute-list ] ] type-specifier [pointer-decl] array-declarator;
    
[ [ default ]
        
[ [ field_attribute-list ] ] type-specifier [pointer-decl] array-declarator;
    
]

[ [function-attribute-list] ] type-specifier [pointer-decl] function-name(
    [ [param-attr-list] ] type-specifier [pointer-decl] array-declarator
    , ...
);

type-attr-list
Specifies zero or more attributes that apply to the type. Valid type attributes include handle, switch_type, transmit_as; the pointer attribute ref, unique, or ptr; and the usage attributes context_handle, string, and ignore. Separate multiple attributes with commas.
type-specifier
Specifies the type identifier, base type, struct, union, or enum type. The type specification can include an optional storage specification.
pointer-decl
Specifies zero or more pointer declarators. A pointer declarator is the same as the pointer declarator used in C, constructed from the * designator, modifiers such as far, and the qualifier const.
array-declarator
Specifies the name of the array, followed by one of the following constructs for each dimension of the array: "[ ]", "[*]", "[const1]", or "[lower...upper]" where lower and upper are constant values that represent the lower and upper bounds. The constant lower must evaluate to zero.
tag
Specifies an optional tag for the structure or union.
field-attribute-list
Specifies zero or more field attributes that apply to the structure, union member, or function parameter. Valid field attributes include first_is, last_is, length_is, max_is, size_is; the usage attributes string, and ignore; the pointer attributes ref, unique, and ptr; and the union attribute switch_type. Separate multiple field attributes with commas. Note that of the attributes listed above, first_is, last_is, and ignore are not valid for unions.
limited-expression
Specifies a C-language expression. The MIDL compiler supports conditional expressions, logical expressions, relational expressions, and arithmetic expressions. MIDL does not allow function invocations in expressions and does not allow increment and decrement operators.
function-attribute-list
Specifies zero or more attributes that apply to the function. Valid function attributes are callback, local; the pointer attribute ref, unique, or ptr; and the usage attributes string, and context_handle.
function-name
Specifies the name of the remote procedure.
param-attr-list
Specifies the directional attributes and one or more optional field attributes that apply to the array parameter. Valid field attributes include max_is, size_is, length_is, first_is, and last_is.

Examples

/* 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..*] 
); 
 

Remarks

Array declarators appear in the interface body of the IDL file as part of a general declaration, as a member of a structure or union declarator, or as a parameter to a remote procedure call.

The bounds of each dimension of the array are expressed inside a separate pair of square brackets. An expression that evaluates to n signifies a lower bound of zero and an upper bound of n – 1. If the square brackets are empty or contain a single asterisk (*), the lower bound is zero and the upper bound is determined at run time.

The array can also contain two values separated by an ellipsis that represent the lower and upper bounds of the array, as in [lower...upper]. Microsoft RPC requires a lower bound of zero. The MIDL compiler does not recognize constructs that specify nonzero lower bounds.

Arrays can be associated with the field attributes size_is, max_is, length_is, first_is, and last_is to specify the size of the array or the part of the array that contains valid data. These field attributes identify the parameter, structure field, or constant that specifies the array dimension or index.

The array must be associated with the identifier specified by the field attribute in this way: When the array is a parameter, the identifier must also be a parameter to the same function; when the array is a structure field, the identifier must be another structure field of that same structure.

An array is called "conformant" if the upper bound of any dimension is determined at run time, and only upper bounds can be determined at run time. To determine the upper bound, the array declaration must include a size_is or max_is attribute.

An array is called "varying" when its bounds are determined at compile time, but the range of transmitted elements is determined at run time. To determine the range of transmitted elements, the array declaration must include a length_is, first_is, or last_is attribute.

A conformant varying array (also called "open") is an array whose upper bound and range of transmitted elements are determined at run time. At most, one conformant or conformant varying array can be nested in a C structure and must be the last element of the structure. Nonconformant varying arrays can occur anywhere in a structure.

Multidimensional Arrays

The user can declare types that are arrays and then declare arrays of objects of such types. The semantics of m-dimensional arrays of n-dimensional array types are the same as the semantics of m+n-dimensional arrays.

For example, the type RECT_TYPE can be defined as a two-dimensional array and the variable rect can be defined as an array of RECT_TYPE. This is equivalent to the three-dimensional array 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 is C-oriented. Following C-language conventions, only the first dimension of a multidimensional array can be determined at run time. Interoperation with DCE IDL arrays that support other languages is limited to:

When the string attribute is used on multidimensional arrays, the attribute applies to the rightmost array.

Arrays of Pointers

Reference pointers must point to valid data. The client application must allocate all memory for an in or in, out array of reference pointers, especially when the array is associated with in, or in, out length_is, or last_is values. The client application must also initialize all array elements before the call. Before returning to the client, the server application must verify that all array elements in the transmitted range point to valid storage.

On the server side, the stub allocates storage for all array elements, regardless of the length_is or last_is value at the time of the call. This feature can affect the performance of your application.

No restrictions are placed on arrays of unique pointers. On both the client and the server, storage is allocated for null pointers. When pointers are non-null, data is placed in preallocated storage.

An optional pointer declarator can precede the array declarator.

When embedded reference pointers are out-only parameters, the server-manager code must assign valid values to the array of reference pointers. For example:

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

The generated stubs allocate the array and assign NULL values to all pointers embedded in the array.

See Also

first_is, IDL, last_is, length_is, max_is, ptr, ref, size_is, string, unique