處理 IDL 檔案中的#defines
此頁面描述為何使用 #define 定義的符號會從 MIDL 編譯器產生的 H 檔案消失,以及可以完成的動作。 本說明適用于 MIDL 處理的任何檔案,例如 *.idl、*.acf、*.h 檔案。
#define符號的擷取是 MIDL 將輸入檔前置處理委派給預處理器的結果。 根據預設,預處理器是建置環境中的 C/C++ 預處理器。 前置處理之後,輸入資料流程 MIDL 接收只會#line預處理器指示詞。 特別是,預處理器會取消註冊輸入檔中的所有巨集定義,因此 MIDL 無法偵測其是否存在。 因此,當 MIDL 將類型定義從輸入檔複寫到產生的 H 檔案時,不會複寫#defines。 因此,如果稍後要從產生的 H 檔案使用,請勿直接在 IDL 檔案中使用#defines。
建議使用下列四個因應措施:
- 使用 const 宣告規格。
- 使用 IDL 檔案中匯入或包含的個別標頭檔,稍後包含在 C 原始程式碼中。
- 在 IDL 檔案中使用列舉常數。
- 使用 cpp_quote 在產生的標頭檔中重現 #define 。
您可以使用 IDL 常數宣告語法重現資訊清單常數。 請注意,IDL 常數宣告中的 const 與 C/C++ const 語意不同,而且只會針對 IDL 編譯引進具名常數。 例如:
const short ARRSIZE = 10
本範例指定 ARRSIZE 是值為 10 的常數。 具名常數可用於 IDL 陣列宣告子,以及 C 程式設計人員使用資訊清單定義的其他位置。 此外,此語法會導致在標頭檔中產生下列這一行:
#define ARRSIZE 10
另一種處理 **#**define 語句的方式是將它們封裝在不同的標頭檔中,無論是封裝成專用於 **#**define 語句的檔案,或是只包含類型定義的檔案。 只包含預處理器指示詞的檔案,可由 IDL 檔案和 C 原始程式檔安全地包含。 雖然指示詞無法在 MIDL 編譯器所產生的標頭檔中使用,但 C 來來源程式可以包含個別的標頭檔。 以類似的方式,可以使用 **#**define 語句和一般類型定義從 IDL 檔案匯入標頭檔。 此方法會封裝 **#**define 和 typedef 語句,方法是在 H 檔案中使用它們,讓 **#**定義符號不會直接用於匯入 IDL 檔案中。 將標頭或 IDL 檔案匯入另一個 IDL 檔案,可防止 typedef 語句複寫至 MIDL 產生的 H 檔案 (,這與 **#**include 語句相反) 。 此方法可讓原始標頭檔從 C 程式碼沿著產生的 H 檔案安全地參考,而不會發生重複定義的問題。
在 IDL 檔案中使用列舉常數也有效。 這些常數可用於 IDL 中的常數運算式,例如,在陣列宣告子中。 C 編譯器預處理器在 MIDL 編譯的早期階段內不會移除列舉常數,因此在 MIDL 編譯器所產生的標頭檔中可以使用列舉常數。 以下列陳述式為例:
typedef enum midlworkaround { MAXSTRINGCOUNT = 300 };
C 預處理器在 MIDL 編譯期間不會移除此語句,且 typedef 將會複寫至產生的 H 檔案。 常數 MAXSTRINGCOUNT 可供 C 來來源程式使用,其中包含 MIDL 編譯器所產生的標頭檔。
最後,MIDL 的 cpp_quote 指示詞可用來直接將任一字元串寫出到產生的 H 檔案中。 例如,若要取得先前在此頁面上使用 cpp_quote的資訊清單常數,可以使用下列語句:
cpp_quote ("#define ARRSIZE 10")
此語句會在標頭檔中產生下列這一行:
#define ARRSIZE 10