MIDL 與 MkTypLib 之間的差異
注意
Mktyplib.exe 工具已經過時。 請改用 MIDL 編譯程式。
MIDL 編譯程式有幾個主要區域與 MkTypLib 不同。 這些差異大多是因為 MIDL 比 MkTypLib 更傾向於 C 語法。
一般而言,您會想要在IDL檔案中使用MIDL語法。 不過,如果您需要編譯現有的 ODL 檔案,或維持與 MkTypLib 的相容性,請使用 /mktyplib203 MIDL 編譯程式選項,強制 MIDL 的行為類似 Mkktyplib.exe版本 2.03。 (這是 MkTypLib 工具的最後一個版本。具體來說,/mktyplib203 選項可解決這些差異:
複雜數據類型的 typedef 語法
在 MkTypLib 中,下列兩個定義都會為類型連結庫中的 「this_struct」 產生TKIND_RECORD。 “struct_tag” 標籤是選擇性的,如果使用的話,就不會顯示在類型連結庫中。
typedef struct struct_tag { ... } this_struct; typedef struct { ... } that_struct;
如果遺漏選擇性標籤,MIDL 將會產生它,有效地將標籤新增至使用者所提供的定義。 由於第一個定義具有標籤,MIDL 會產生 「this_struct」 的TKIND_RECORD和 「this_struct」 的TKIND_ALIAS(將 “this_struct” 定義為 “struct_tag” 的別名)。 因為第二個定義中遺漏了卷標,MIDL 會產生TKIND_RECORD,因為 MIDL 會在 MIDL 內部產生一個對使用者而言沒有意義的名稱,而對 “that_struct” 的TKIND_ALIAS並不有意義。
這可能會影響類型連結庫瀏覽器,這些瀏覽器只會在其使用者介面中顯示記錄的名稱。 如果您預期TKIND_RECORD具有實名,則無法辨識的名稱可能會出現在使用者介面中。 此行為也適用於 等位 和 列舉 定義,而 MIDL 編譯程式會分別產生TKIND_UNIONs和TKIND_ENUMs。
MIDL 也允許 C 樣式 結構、等位和 列舉 定義。 例如,下列定義在 MIDL 中是合法的:
struct my_struct { ... }; typedef struct my_struct your_struct;
布爾數據類型
在 MkTypLib 中,布爾值 基底型別和 MkTypLib 數據類型 BOOL 等同於VT_BOOL,其對應至 VARIANT_BOOL,且定義為 簡短。 在 MIDL 中,布林值 基底類型相當於 VT_UI1,其定義為 不帶正負號的字元,而 BOOL 數據類型會定義為 長。 如果您在相同的檔案中混合IDL語法和ODL語法,但仍嘗試維持與 MkTypLib 的相容性,這會導致困難。 因為數據類型的大小不同,封送處理程式代碼不符合類型資訊中所述的內容。 如果您想要在類型連結庫中VT_BOOL,您應該使用 VARIANT_BOOL 數據類型。
標頭檔中的 GUID 定義
在 MkTypLib 中,GUID 定義於頭檔中,其中包含可有條件地編譯以產生 GUID 預先定義或具現化 GUID 的巨集。 MIDL 通常會將 GUID 預先定義放在其產生的頭檔中,而 GUID 具現化只會放在 /iid 參數所產生的檔案中。
使用 /mktyplib203 參數,無法解決下列行為差異:
區分大小寫
MIDL 區分大小寫,OLE 自動化不是。
列舉宣告中的符號範圍
在 MkTypLib 中,列舉中的符號範圍是 local。 在 MIDL 中,列舉中的符號範圍是全域的,因為它是 C。例如,下列程式代碼會在 MkTypLib 中編譯,但在 MIDL 中會產生重複的名稱錯誤:
typedef struct { ... } a; enum {a=1, b=2, c=3};
公用屬性的範圍
如果您將 公用 屬性套用至介面區塊,MkTypLib 會將該介面區塊內的每個 typedef 視為公用。 MIDL 會要求您明確將 public 屬性套用至您想要公用的 typedefs。
Importlib 搜尋順序
如果您匯入多個類型連結庫,而且如果這些連結庫包含重複的參考,MkTypLib 會使用找到的第一個參考來解決此問題。 MIDL 會使用它找到的最後一個參考。 例如,假設使用下列 ODL 語法,連結庫 C 會使用連結庫 A 中的 MOO typedef,如果您使用 MkTypLib 進行編譯,而且如果您使用 MIDL 編譯,則連結庫 B 中的 MOO typedef:
[...]library A { typedef struct tagMOO {...}MOO } [...]library B { typedef struct tagMOO {...} MOO } [...]library C { importlib (A.TLB) importlib (B.TLB) typedef struct tagBAA {MOO y;}BAA }
適當的因應措施是使用正確的匯入連結庫名稱來限定每個這類參考,如下所示:
typedef struct tagBAA {A.MOO y;}BAA
無法辨識 VOID 資料類型
MIDL 會辨識 C 語言 void 數據類型,而且無法辨識 OLE Automation VOID 數據類型。 如果您有使用 VOID 的 ODL 檔案,請將此定義放在檔案頂端:
#define VOID void '''
指數表示法
MIDL 要求以指數表示法表示的值包含在引號內。 例如,“-2.5E+3”
LCID 值和常數
在剖析檔案時,MIDL 通常不會考慮 LCID。 若要強制這個值的行為,或如果您需要在定義常數時使用地區設定特定的表示法,請以引號括住值或常數。
如需詳細資訊,請參閱 /mktyplib203、/iid和 封送處理 OLE 數據類型。