MIDL 配列
配列宣言子は、IDL ファイルのインターフェース本体に次のいずれかとして表示されます。
- 一般宣言の一部
- 構造体または共用体宣言子のメンバー
- リモート プロシージャ コールのパラメータ
配列の各次元の境界は、別々の角括弧のペア内に表現されます。 n と評価される式は、下限が 0、上限が n - 1 であることを示します。 角括弧が空であるか、単一のアスタリスク (*) が含まれている場合、下限は 0 になり、上限は実行時に決定されます。
配列には、[lower...upper] のように、配列の下限と上限を表す省略記号で区切られた 2 つの値を含めることもできます。 Microsoft RPC では下限がゼロである必要があります。 MIDL コンパイラは、ゼロ以外の下限を指定する構造を認識しません。
配列は、フィールド属性 size_is、 max_is、 0>length_is、 first_is、および last_is に関連付けて、配列のサイズまたは有効なデータを含む配列の部分を指定できます。 これらのフィールド属性は、配列の次元またはインデックスを指定するパラメーター、構造体フィールド、または定数を識別します。
配列は、フィールド属性によって指定された識別子に次のように関連付けられる必要があります。配列がパラメーターである場合、識別子は同じ関数のパラメーターでなければなりません。配列が構造体フィールドである場合、識別子は同じ構造体の別の構造体フィールドでなければなりません。
実行時に任意の次元の上限が決定される場合、配列は「準拠」していると呼ばれます。 (実行時に決定できるのは上限のみです。) 上限を決定するには、配列宣言に size_is または max_is 属性を含める必要があります。
配列の境界はコンパイル時に決定されますが、送信される要素の範囲は実行時に決定される場合、その配列は「可変」と呼ばれます。 送信される要素の範囲を決定するには、配列宣言に length_is、 first_is、または last_is 属性を含める必要があります。
適合可変配列 (「オープン」とも呼ばれる) は、送信される要素の上限と範囲が実行時に決定される配列です。 C 構造体内にネストできる適合配列または適合可変配列は最大で 1 つであり、構造体の最後の要素である必要があります。 対照的に、非適合可変配列は構造内のどこにでも出現する可能性があります。
例
/* 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 は 2 次元配列として定義でき、変数 rect は RECT_TYPE の配列として定義できます。 これは次の3次元配列 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 配列との相互運用性は、次のものに制限されます。
- 定数(コンパイル時に決定される)境界を持つ多次元配列。
- 最初の次元を除くすべての境界が定数である多次元配列。 最初の次元の送信される要素の上限と範囲は、実行時間に依存します。
- 下限がゼロの任意の 1 次元配列。
[string] 属性が多次元配列で使用される場合、属性は右端の配列に適用されます。
ポインタの配列
参照ポインターは有効なデータを指す必要があります。 クライアント アプリケーションは、特に配列が [in]、または [ in,out]、 [length_is]、または [last_is] 値に関連付けられている場合、参照ポインターの [in] または [ in,out] 配列にすべてのメモリを割り当てる必要があります。 クライアント アプリケーションは、呼び出しの前にすべての配列要素を初期化する必要もあります。 サーバー アプリケーションは、クライアントに戻る前に、送信された範囲内のすべての配列要素が有効なストレージを指していることを確認する必要があります。
サーバー側では、呼び出し時の [length_is] または [last_is] の値に関係なく、スタブはすべての配列要素にストレージを割り当てます。 この機能はアプリケーションのパフォーマンスに影響を与える可能性があります。
一意のポインタの配列には制限はありません。 クライアントとサーバーの両方で、ヌル ポインター用のストレージが割り当てられます。 ポインタが null 以外の場合、データは事前に割り当てられたストレージに配置されます。
オプションのポインタ宣言子を配列宣言子の前に置くことができます。
埋め込まれた参照ポインターが [out] のみのパラメーターである場合、サーバー マネージャー コードは参照ポインターの配列に有効な値を割り当てる必要があります。 次に例を示します。
typedef [ref] short * ARefPointer;
typedef ARefPointer ArrayOfRef[10];
HRESULT proc1( [out] ArrayOfRef Parameter );
生成されたスタブは配列を割り当て、配列に埋め込まれたすべてのポインターに null 値を割り当てます。