次の IDL ファイルの例は、インターフェイス定義の基本的な構造を示しています。 メモリ割り当て、カスタム マーシャリング、非同期メッセージングは、カスタム COM インターフェイスに実装できる機能のほんの一部です。 MIDL 属性は、COM インターフェイスを定義するために使用されます。 MIDL 属性の概要など、インターフェイスとタイプ ライブラリの実装の詳細については、「MIDL プログラマ ガイドとリファレンス」の「インターフェイス定義とタイプ ライブラリ」を参照してください。 すべての MIDL 属性、キーワード、ディレクティブの完全なリファレンスについては、MIDL 言語リファレンスを参照してください。
Example.idl
次の IDL ファイルの例では、2 つの COM インターフェイスが定義されています。 この IDL ファイルから、Midl.exe はプロキシ/スタブを生成し、コード ファイルとヘッダー ファイルをマーシャリングします。 この例では、1 行ずつの解剖を行います。
//
// Example.idl
//
import "mydefs.h","unknwn.idl";
[
object,
uuid(a03d1420-b1ec-11d0-8c3a-00c04fc31d2f),
] interface IFace1 : IUnknown
{
HRESULT MethodA([in] short Bread, [out] BKFST * pBToast);
HRESULT MethodB([in, out] BKFST * pBPoptart);
};
[
object,
uuid(a03d1421-b1ec-11d0-8c3a-00c04fc31d2f),
pointer_default(unique)
] interface IFace2 : IUnknown
{
HRESULT MethodC([in] long Max,
[in, max_is(Max)] BkfstStuff[ ],
[out] long * pSize,
[out, size_is( , *pSize)] BKFST ** ppBKFST);
};
ここでは、IDL import ステートメントを使用して、ユーザー定義型を含むヘッダー ファイル Mydefs.h と、IFace1 と IFace2 の派生元 IUnknownの定義を含む Unknwn.idl を取り込みます。
オブジェクト 属性は、インターフェイスをオブジェクト インターフェイスとして識別し、RPC クライアントとサーバー スタブの代わりにプロキシ/スタブ コードを生成するように MIDL コンパイラに指示します。 オブジェクト インターフェイス メソッドには、HRESULT戻り値の型が必要です。これにより、基になる RPC メカニズムは、ネットワークの問題が原因で完了できなかった呼び出しのエラーを報告できます。
uuid 属性は、インターフェイス識別子 (IID) を指定します。 各インターフェイス、クラス、タイプ ライブラリは、独自の一意識別子で識別する必要があります。 ユーティリティ Uuidgen.exe を使用して、インターフェイスやその他のコンポーネント用に一意の ID のセットを生成します。
インターフェイス キーワードは、インターフェイス名を定義します。 すべてのオブジェクト インターフェイスは、IUnknownから直接または間接的派生する必要があります。
方向パラメーターの 、呼び出し元のみが設定するパラメーターを指定します。 out パラメーターは、呼び出し元に返されるデータを指定します。 1 つのパラメーターで両方の方向属性を使用すると、パラメーターを使用してメソッドにデータを送信し、データを呼び出し元に渡すことができます。
pointer_default 属性は、パラメーター リストに含まれるポインターを除くすべてのポインターの既定のポインター型 (一意の、ref、または ptr) を指定します。 既定の型が指定されていない場合、MIDL は単一ポインターが一意の と見なします。 ただし、複数のレベルのポインターがある場合は、既定の型を一意の する場合でも、既定のポインター型を明示的に指定する必要があります。
前の例では、配列 BkfstStuff[ ] は 準拠配列であり、そのサイズは実行時に決定されます。 max_is 属性は、配列インデックスの最大値を含む変数を指定します。
size_is 属性は、配列のサイズを指定したり、前の例のように複数レベルのポインターを指定したりするためにも使用されます。 この例では、返されるデータの量を事前に知らなくても呼び出しを行うことができます。
Example2.idl
次の IDL の例 (前の IDL の例で説明したインターフェイスを再利用) は、インターフェイスのタイプ ライブラリ情報を生成するさまざまな方法を示しています。
//
// Example2.idl
//
import "example.idl","oaidl.idl";
[
uuid(a03d1422-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("IFace3 interface"),
pointer_default(unique);
dual,
oleautomation
]
interface IFace3 : IDispatch
{
HRESULT MethodD([in] BSTR OrderIn,
[out, retval] * pTakeOut);
}; //end IFace3 def
[
uuid(a03d1423-b1ec-11d0-8c3a-00c04fc31d2f),
version(1.0),
helpstring("Example Type Library"),
] library ExampleLib
{
importlib("stdole32.tlb");
interface IFace3;
[
uuid(a03d1424-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("Breakfast Component Class")
] coclass BkfstComponent
{
[default]interface IFace1;
interfaceIFace2
}; //end coclass def
[
uuid(a03d1424-b1ec-11d0-8c3a-00c04fc31d2f),
helpstring("IFace4 interface"),
pointer_default(unique);
dual,
oleautomation
]
interface IFace4 : IDispatch
{
[propput] HRESULT MethodD([in] BSTR OrderIn);
[propget] HRESULT MethodE([out, retval] * pTakeOut);
}; //end IFace4 def
}; //end library def
helpstring 属性は省略可能です。これを使用して、オブジェクトを簡単に説明したり、ステータス行を指定したりします。 これらのヘルプ文字列は、Microsoft Visual Basic で提供されるオブジェクト ブラウザーなど、オブジェクト ブラウザーで読み取り可能です。
IFace3 の デュアル 属性は、ディスパッチ インターフェイスと COM インターフェイスの両方であるインターフェイスを作成します。 これは IDispatch から派生しているため、デュアル インターフェイスは Automation をサポートします。これは、oleautomation 属性で指定されます。 IFace3 は Oaidl.idl をインポートして、IDispatch の定義取得します。
ライブラリ ステートメントでは、独自の uuid、helpstring、バージョン 属性を持つ ExampleLib タイプ ライブラリを定義します。
タイプ ライブラリ定義内で、importlib ディレクティブはコンパイル済みのタイプ ライブラリを取り込みます。 すべてのタイプ ライブラリ定義は、Stdole32.tlb で定義されている基本タイプ ライブラリを取り込む必要があります。
このタイプ ライブラリ定義は、タイプ ライブラリにインターフェイスを含める 3 つの異なる方法を示しています。 IFace3 は、ライブラリ ステートメント内で参照するだけで含まれます。
コクラス ステートメントは、以前に定義した 2 つのインターフェイスである IFace1 と IFace2 を含む、まったく新しいコンポーネント クラス BkfstComponent を定義します。 既定の属性は、IFace1 を既定のインターフェイスとして指定します。
IFace4 はライブラリ ステートメント内で記述されています。 MethodD の propput 属性は、メソッドが同じ名前のプロパティに対して設定アクションを実行することを示します。 propget 属性は、メソッドがメソッドと同じ名前のプロパティから情報を取得することを示します。 MethodD の retval 属性は、関数の戻り値を含む出力パラメーターを指定します。