MIDL 数组

数组声明符会显示在 IDL 文件的接口正文中,如下所示:

  • 常规声明的一部分
  • 结构或联合声明符的成员
  • 远程过程调用的参数

数组的每个维度的边界均会在单独的一对方括号内表示。 计算结果为 n 的表达式表示下限为 0 而上限为 n - 1。 如果方括号为空或包含单个星号 (*),则下限为零,而上限将在运行时确定。

该数组还可包含两个用省略号分隔的值,而这些值分别表示数组的下限和上限,如 [下限...上限] 所示。 Microsoft RPC 要求下限为零。 MIDL 编译器无法识别指定非零下限的构造。

数组可与字段属性 size_ismax_islength_isfirst_islast_is 进行关联,从而指定数组的大小或是指定包含有效数据的数组组成部分。 这些字段属性可标识用于指定数组维度或索引的参数、结构字段或常量。

该数组必须通过以下方式与此字段属性指定的标识符相关联:当该数组为某一参数时,此标识符也须为同一函数的参数;当该数组为某一结构字段时,此标识符必须为同一结构的其他结构字段。

如果某一数组的任一维度的上限均会在运行时确定,该数组则被称为“一致”数组。 (只能在运行时确定上限。)若要确定上限,数组声明必须包含 size_ismax_is 属性。

当某一数组的边界是在编译时确定,但已传输元素的范围是在运行时确定时,该数组则被称为“可变”数组。 若要确定已传输元素的范围,数组声明则须包括 length_isfirst_islast_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..*] 
);

有关详细信息,请参阅数组和指针

多维数组

用户可声明属于数组的类型,然后声明此类型的对象的数组。 n 维数组类型的 m 维数组的语义与 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 语言约定,因此在运行时只能确定多维数组的第一个维度。 与支持其他语言的 DCE IDL 数组进行的互操作仅限于:

  • 具有恒定(编译时确定)边界的多维数组。
  • 除第一个维度外,具有所有恒定边界的多维数组。 第一个维度的已传输元素的上限和范围取决于运行时。
  • 下限为零的任意一维数组。

[string] 属性用于多维数组时,该属性将应用于最右侧的数组。

指针数组

引用指针必须指向有效数据。 客户端应用程序必须为引用指针的 [in][ in,out] 数组分配所有内存,尤其是当该数组与 [in][ in,out][length_is] 或是 [last_is] 值关联时。 客户端应用程序还须在调用前初始化所有数组元素。 返回到客户端之前,服务器应用程序必须确保已传输范围内的所有数组元素均指向有效存储。

在服务器端,存根会为所有数组元素分配存储,而不考虑调用时的 [length_is][last_is] 值为何。 此特性可能会影响应用程序的性能。

唯一指针的数组不存在任何限制。 在客户端和服务器端,均会为 null 指针分配存储。 当指针为非 null 时,会将数据置于预先分配的存储中。

可选指针声明符可位于数组声明符之前。

当嵌入引用指针为仅 [out] 参数时,服务器管理器代码须将有效值分配给引用指针的数组。 例如:

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

生成的存根会分配数组,并将 null 值分配给数组中嵌入的所有指针。