IDL 檔案的結構
這些範例IDL檔案示範介面定義的基本建構。 記憶體配置、自定義封送處理和異步傳訊只是您可以在自定義 COM 介面中實作的一些功能。 MIDL 屬性可用來定義 COM 介面。 如需實作介面和類型連結庫的詳細資訊,包括 MIDL 屬性的摘要,請參閱 MIDL 程式設計人員指南和參考中的介面定義和類型連結庫 。 如需所有 MIDL 屬性、關鍵詞和指示詞的完整參考,請參閱 MIDL 語言參考。
Example.idl
下列範例 IDL 檔案會定義兩個 COM 介面。 從這個 IDL 檔案中,Midl.exe會產生 Proxy/存根和封送處理程式碼和標頭檔。 逐行剖析會遵循此範例。
//
// 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,其中包含使用者定義型別,以及 Unknwn.idl,其中包含 IFace1 和 IFace2 衍生自 IUnknown 的定義。
對象屬性會將介面識別為物件介面,並指示 MIDL 編譯程式產生 Proxy/stub 程式代碼,而不是 RPC 用戶端和伺服器存根。 物件介面方法必須具有 HRESULT 的傳回類型,以允許基礎 RPC 機制報告因網路問題而無法完成之呼叫的錯誤。
uuid 屬性會指定介面標識碼 (IID)。 每個介面、類別和類型連結庫都必須使用自己的唯一標識碼來識別。 使用公用程式Uuidgen.exe為您的介面和其他元件產生一組唯一標識符。
interface 關鍵詞會定義介面名稱。 所有物件介面都必須直接或間接衍生自 IUnknown。
方向參數會指定只有呼叫端所設定的參數。 out 參數會指定傳回給呼叫端的數據。 在一個參數上使用這兩個方向屬性,指定參數同時用來將數據傳送至 方法,以及將數據傳回給呼叫端。
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 的定義。
連結 庫 語句會定義 ExampleLib 類型連結庫,其有自己的 uuid、 helpstring 和 版本 屬性。
在類型連結庫定義中, importlib 指示詞會帶入已編譯的類型連結庫。 所有類型連結庫定義都應該帶入 Stdole32.tlb 中定義的基底類型庫。
此類型連結庫定義示範在類型連結庫中包含介面的三種不同方式。 IFace3 僅藉由在連結庫語句中參考它來包含。
coclass 語句會定義全新的元件類別 BkfstComponent,其中包含兩個先前定義的介面 IFace1 和 IFace2。 默認屬性會將IFace1指定為預設介面。
IFace4 會在連結庫語句中描述。 MethodD 上的 propput 屬性表示方法在相同名稱的屬性上執行設定動作。 propget 屬性表示方法會從與 方法同名的屬性擷取資訊。 MethodD 中的 retval 屬性會指定包含函式傳回值的輸出參數。