IDLファイルの構造

これらのIDLファイルの例は、インターフェイス定義の基本的な構成要素を示しています。 メモリ割り当て、カスタムマーシャリング、および非同期メッセージングは、カスタムCOMインターフェイスに実装できる機能のほんの一部です。 MIDL属性は、COMインターフェイスを定義するために使用されます。 MIDL属性の概要など、インターフェイスとタイプライブラリの実装の詳細については、 「MIDLプログラマーズガイドおよびリファレンス」 の 「インターフェイス定義とタイプライブラリ」 を参照してください。 すべてのMIDL属性、キーワード、およびディレクティブの完全なリファレンスについては、 「MIDL言語リファレンス」 を参照してください。

例.idl

次のIDLファイルの例では、2つのCOMインターフェイスを定義します。 このIDLファイルから、Midl.exeはプロキシ/スタブとマーシャリングのコードとヘッダーファイルを生成します。 この例では、行ごとの分析を行います。

//
// 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の定義を含むIUnknownを取り込みます。

object属性は、インターフェイスをオブジェクトインターフェイスとして識別し、RPCクライアントおよびサーバースタブの代わりにプロキシ/スタブコードを生成するようにMIDLコンパイラに指示します。 オブジェクトインターフェイスメソッドの戻り値の型はHRESULTである必要があります。これにより、基になるRPCメカニズムは、ネットワークの問題が原因で完了しなかった呼び出しのエラーを報告できます。

uuid属性は、インターフェイス識別子 (IID) を指定します。 各インターフェイス、クラス、およびタイプライブラリは、独自の一意の識別子で識別する必要があります。 ユーティリティUuidgen.exeを使用して、インターフェイスおよびその他のコンポーネントの一意のIdのセットを生成します。

interface キーワードは、インターフェイス名を定義します。 すべてのオブジェクトインターフェイスは、IUnknownから直接または間接的に派生する必要があります。

in方向パラメーターは、呼び出し元によってのみ設定されるパラメーターを指定します。 outパラメーターは、呼び出し元に返されるデータを指定します。 1つのパラメーターで両方の方向属性を使用すると、メソッドにデータを送信し、呼び出し元にデータを渡すためにパラメーターが使用されることを指定します。

pointer_default属性は、パラメーターリストに含まれているものを除くすべてのポインターに対して、既定のポインター型(unique, ref, または ptr)を指定します。 既定の型が指定されていない場合、MIDLは単一のポインターが一意であると見なします。 ただし、複数のレベルのポインターがある場合は、既定の型を一意にする場合でも、既定のポインター型を明示的に指定する必要があります。

先の例では、配列BkfstStuff[ ]は適合配列であり、そのサイズは実行時に決定される。 max_is属性は、配列インデックスの最大値を含む変数を指定します。

size_is属性は、配列のサイズを指定するため、または前の例のように複数のレベルのポインターを指定するためにも使用されます。 この例では、返されるデータの量を事前に把握しなくても呼び出しを行うことができます。

例2.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のdual属性は、ディスパッチインターフェイスとCOMインターフェイスの両方であるインターフェイスを作成します。 IDispatchから派生しているため、デュアルインターフェイスはオートメーションをサポートします。これは、oleautomation 属性で指定されています。 IFace3はOaidl.idlをインポートしてIDispatchの定義を取得します。

libraryステートメントは、独自のuuid, helpstring、およびversion属性を持つExampleLibタイプライブラリを定義します。

タイプライブラリ定義内で、importlibディレクティブはコンパイルされたタイプライブラリを取り込みます。 すべてのタイプライブラリ定義は、Stdole32.tlbで定義されている基本タイプライブラリを取り込む必要があります。

このタイプライブラリ定義は、タイプライブラリにインターフェイスを含める3つの異なる方法を示しています。 IFace3は、libraryステートメント内で参照するだけで含まれます。

coclassステートメントでは、まったく新しいコンポーネント・クラスであるBkfstComponentを定義しており、以前に定義された2つのインターフェース、IFace1とIFace2を含んでいる。 default属性は、IFace1`を既定のインターフェイスとして指定します。

IFace4は、libraryステートメント内で記述されます。 MethodDのpropput属性は、メソッドが同じ名前のプロパティに対してsetアクションを実行することを示します。 propget属性は、メソッドがメソッドと同じ名前のプロパティから情報を取得することを示します。 MethodDのretval属性は、関数の戻り値を含む出力パラメーターを指定します。