MIDL 配列
配列宣言子は、IDL ファイルのインターフェイス本文に次のいずれかとして表示されます。
- 一般的な宣言の一部
- 構造体または共用体宣言子のメンバー
- リモート プロシージャ呼び出しのパラメーター
配列の各次元の境界は、別々の角かっこのペア内で表されます。 n に評価される式は、下限が 0 で、上限が n から 1 であることを示します。 角かっこが空の場合、またはアスタリスク (*)が 1 つ含まれている場合、下限は 0 で、上限は実行時に決定されます。
配列には、[lower..] のように、配列の下限と上限を表す省略記号で区切られた 2 つの値を含めることもできます。upper]。 Microsoft RPC では、下限が 0 である必要があります。 MIDL コンパイラは、0 以外の下限を指定するコンストラクトを認識しません。
配列は、size_is、max_is、length_is、first_is、およびlast_isのフィールド属性に関連付けて、有効なデータを含む配列のサイズまたは配列の一部を指定できます。 これらのフィールド属性は、配列の次元またはインデックスを指定するパラメーター、構造体フィールド、または定数を識別します。
配列は、フィールド属性で指定された識別子に次のように関連付ける必要があります。配列がパラメーターの場合、識別子も同じ関数のパラメーターである必要があります。配列が構造体フィールドの場合、識別子はその同じ構造体の別の構造体フィールドである必要があります。
任意の次元の上限が実行時に決定された場合、配列は "準拠" と呼ばれます。 (実行時に上限のみを決定できます)。上限を決定するには、配列宣言に size_isまたはmax_is 属性 を 含める必要があります。
配列は、コンパイル時に境界が決定されるときに "varying" と呼ばれますが、送信される要素の範囲は実行時に決定されます。 送信される要素の範囲を決定するには、配列宣言に length_is、first_is、または last_is属性 を 含める必要があります。
適合する可変配列 ("open" とも呼ばれます) は、実行時に送信される要素の上限と範囲が決定される配列です。 多くの場合、1 つの準拠配列または準拠する配列を 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 次元配列のセマンティクスは、mn+ 次元配列のセマンティクスと同じです。
たとえば、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 配列との相互運用は、次に制限されます。
- 定数 (コンパイル時に決定された) 境界を持つ多次元配列。
- 最初の次元を除くすべての定数境界を持つ多次元配列。 最初のディメンションの送信される要素の上限と範囲は、実行時に依存します。
- 下限が 0 の 1 次元配列。
多次元配列で [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 値を割り当てます。