Microsoft介面定義語言
Microsoft介面定義語言(英語:Microsoft Interface Definition Language;縮寫:MIDL)是微軟的基於文字的介面描述語言。擴充自DCE/RPC IDL用於微軟的組件對象模型(Component Object Model)。 [1] 它的編譯器是MIDL.exe(隨Windows SDK發行)。MIDL用於遠端程序呼叫(RPC)的介面、DCOM介面、OLE自動化的類型庫等的描述.
簡介
每個IDL檔案包含一個或多個interface定義。每個interface定義由interface頭部與interface體組成。interface頭部給出了介面的整體資訊;如果含關鍵字object,表示這是一個COM介面,否則表示這是一個DCE RPC介面。interface體給出了所有需要暴露的資訊。
IDL檔案中一個介面的結構資訊:
[ //header
//Interface attributes go here.
]
interface INTERFACENAME //body
{
//The interface body goes here.
}
library TyeLibraryFileName
{
//Type library Information
}
IDL檔案介面範例:
[
object,
uuid(C0E20128-DB19-4DB3-BCA1-24595E5E24A8),
dual,
nonextensible,
helpstring("IConfig Interface"),
pointer_default(unique)
]
interface ILogManager : IDispatch
{
[id(1), helpstring("Initializes ILogManager")] HRESULT Initialize([in] IConfig* Config);
[id(2), helpstring("Logs MemberClaims")] HRESULT LogMemberClaims([in] IMember* Member);
[id(3), helpstring("Logs ILogData to specified destination")]
HRESULT Log([in] ILogData* LogData);
};
library MyTypeLibraryFileLib
{
[
uuid(B3F6C9C4-26AE-451B-9788-75F6C648DBF4),
helpstring("LogManager Class")
]
coclass LogManager
{
[default] interface ILogManager;
};
}
類型庫用於向編譯器提供關於類、介面、列舉等的COM對象或COM介面的資訊。類型庫是二進制檔案。MIDL編譯器處理IDL檔案並建立類型庫檔案、標頭檔、proxy檔案。例如:
midl myfilectl.idl /tlb myfilectl.tlb /h
其中/h產生C++標頭檔。
MIDL編譯器編譯name.idl預設產生的檔案,對於RPC介面為:
Client stub (name_c.c) Server stub (name_s.c) Header file (name.h)
對於COM介面預設產生的檔案:
Interface proxy/stub file (name_p.c) 给客户/服务器的surrogate entry points Interface header file (name.h) 包含IDL文件中定义的接口的类型定义与函数声明,以及stub调用的子例程的前向声明。 Interface UUID file (name_i.c) 接口ID文件,定义IDL文件中的每个接口的GUID 类型库文件(name.tlb) Dlldata.c 创建proxy/stub DLL所需要的数据
如果介面屬性列表中有local屬性,編譯進產生介面的標頭檔, Name.h.
歷史
MIDL 3.0版支援按照類似於C#語言的格式寫idl檔案。這要求使用Windows SDK 10.0.17134.0版或以上,其所包含的midl.exe 為8.01.0622版或以上,編譯時使用/winrt選項。[2] 介面中的非local的成員函數返回類型只能是HRESULT 或 SCODE,早於3.0的版本還允許返回類型為void,但這種3.0版本中將編譯報錯。
語言內容
介面可以前向聲明,以便被參照。
類型定義(typedef)、construct聲明、import指令(類似於C語言預處理器include指令),可以出現在interface體的外部。IDL檔案的這些定義都會出現在產生的標頭檔中;所有介面的所有過程都會被建立stub常式。
MIDL資料類型
陣列定義遵從C語言的標準,陣列下界必須為0。 一對方括號內如果只有一個數,表示陣列下界為0上界為N-1;如果方括號內為*號,表示下界為0上界在執行時確定;[lower...upper]明確給出上下限。多維陣列只有最左維可以不在編譯時指定。
封裝的聯合類型(encapsulated union)是指類型的通過switch定義的判別數據成員(discriminant)也被封裝在類型中。如下例:
typedef union _S1_TYPE switch (long l1) U1_TYPE
{
case 1024:
float f1;
case 2048:
double d2;
} S1_TYPE;
/* 在产生的头文件中: */
typedef struct _S1_TYPE
{
long l1;
union
{
float f1;
double d2;
} U1_TYPE;
} S1_TYPE;
類型庫
類型庫是二進制檔案(.tlb)包含了一個ActiveX應用程式暴露的類型與對象的資訊。可包括:
- 資料類型資訊,如:aliases, enumerations, structures, unions.
- 對象描述,每一個這樣的描述稱作typeinfo。如:module, interface, IDispatch interface (dispinterface), component object class (coclass). 可以理解介面是抽象類,coclass是介面的物理實現類。
- 參照別的類型庫的類型描述。
類型庫可以是midl編譯產生的單獨的二進制檔案(.tlb,表示type library)。也可以用資源編譯器(rc.exe)把.tlb檔案增加到DLL或exe檔案中。帶有1個或多個類型庫資源的DLL典型具有副檔名.olb (object library). tlb檔案在資原始檔(.rc)中必須寫成如下形式,帶有整數辨識符、類型為TypeLib:
1 typelib mylib1.tlb 2 typelib mylib2.tlb
把tlb登記在Windows登錄檔,可以用.NET FRAMEWOK帶有的regtlibv12.exe,通常在這樣的目錄下:
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe
各種類型庫工具(如編譯器、object browser等)通過 ITypeLib 這樣的介面訪問二進制類型庫資訊。
類型庫描述語言是ODL,最頂層語法結構是library陳述式。
MIDL的資料類型中, boolean基礎類型等價於VT_UI1;BOOL資料類型被定義為long;如果希望使用VT_BOOL,那應該用VARIANT_BOOL資料類型。
下述代碼裝入並在Windows登錄檔中註冊一個類型庫:
ITypeLib *pTypeLib;
HRESULT hr;
hr = LoadTypeLibEx("example.tlb", REGKIND_REGISTER, &pTypeLib);
if(SUCCEEDED(hr))
{
pTypeLib->Release();
} else {
exit(0); // Handle errors here.
}
參見
參考文獻
- ^ MSDN Reference. [2016-12-29]. (原始內容存檔於2008-04-11).
- ^ MSDN:"Introduction to Microsoft Interface Definition Language 3.0". [2018-12-05]. (原始內容存檔於2021-02-01).