#import 指示詞 (C++)
C++ 特定
用來加入類型程式庫中的資訊。 類型程式庫的內容會轉換成 C++ 類別,多半是在描述 COM 介面。
語法
#import 「 filename 」 [ attributes ]
#import < 檔名 > [ 屬性]
參數
檔案名稱
指定要匯入的類型程式庫。 檔案名 可以是下列其中一種:
包含類型程式庫之檔案的名稱,例如 .olb、.tlb 或 .dll 檔。 關鍵字
file:
,可以在每個檔案名之前。類型程式庫中的控制項 ProgID。 關鍵字
progid:
,可以在每個 progid 之前。 例如:#import "progid:my.prog.id.1.5"
如需程式的詳細資訊,請參閱 指定當地語系化識別碼和版本號碼 。
當您在 64 位作業系統上使用 32 位交叉編譯器時,編譯器只能讀取 32 位登錄區。 您可能會想要使用原生 64 位元編譯器,建置並註冊 64 位元類型程式庫。
類型程式庫的程式庫 ID。 關鍵字
libid:
,可以在每個程式庫識別碼之前。 例如:#import "libid:12341234-1234-1234-1234-123412341234" version("4.0") lcid("9")
如果您未指定
version
或 ,則 套用至progid:
的規則 也會套用至libid:
lcid
。可執行檔 (.exe)。
程式庫 (.dll) 檔案,其中包含類型程式庫資源(例如 .ocx)。
包含類型程式庫的複合文件。
LoadTypeLib API 可以理解 的任何其他檔案格式。
attributes
一或多個 #import 屬性 。 使用空格或逗號分隔屬性。 例如:
#import "..\drawctl\drawctl.tlb" no_namespace, raw_interfaces_only
-或-
#import "..\drawctl\drawctl.tlb" no_namespace raw_interfaces_only
備註
檔案名的搜尋順序
檔案名 前面選擇性地加上目錄規格。 檔案名稱必須指定現有的檔案名稱。 兩個語法形式之間的差異在於未完整指定路徑時,前置處理器搜尋類型程式庫檔案的順序。
語法形式 | 動作 |
---|---|
有引號的形式 | 指示預處理器先在包含 #import 語句的檔案目錄中尋找類型程式庫檔案,然後在檔案中包含 ( #include ) 檔案的目錄中。 然後,前置處理器會沿著如下所示的路徑搜尋。 |
角括弧形式 | 指示前置處理器依照下列路徑搜尋類型程式庫檔案: 1. PATH 環境變數路徑清單2. LIB 環境變數路徑清單3. /I 編譯器選項所指定的 路徑,但編譯器會搜尋從另一個具有 no_registry 屬性之類型程式庫參考的型別程式庫 。 |
指定當地語系化識別碼和版本號碼
當您指定 ProgID 時,也可以指定 ProgID 的當地語系化 ID 和版本號碼。 例如:
#import "progid:my.prog.id" lcid("0") version("4.0)
如果您未指定當地語系化識別碼,則會根據下列規則選擇 progid:
如果只有一個當地語系化識別碼,則會使用該當地語系化識別碼。
如果有一個以上的當地語系化識別碼,則會使用版本號碼為 0、9 或 409 的第一個當地語系化識別碼。
如果有一個以上的當地語系化識別碼,且其中沒有任何一個是 0、9 或 409,則會使用最後一個。
如果您未指定版本號碼,則會使用最新版本。
匯入所建立的標頭檔
#import 會建立兩個標頭檔,以重新建構 C++ 原始程式碼中的型別程式庫內容。 主要標頭檔類似于 Microsoft 介面定義語言 (MIDL) 編譯器所產生的標頭檔,但具有其他編譯器產生的程式碼和資料。 主要 標頭檔 與類型程式庫具有相同的基底名稱,加上 。TLH 擴充功能。 次要標頭檔具有和類型程式庫相同的基底名稱,再加上 .TLI 副檔名。 它包含編譯器產生的成員函式的實作,而且已在主要標頭檔中包含 (#include
)。
如果匯入使用 byref
參數的 dispinterface 屬性, #import 不會產生 函式的 __declspec(property) 語句。
這兩個標頭檔都會放在 /Fo (name 物件檔) 選項所 指定的輸出目錄中。 然後,編譯器會讀取和編譯它們,就像主要標頭檔是由 指示詞命名一 #include
樣。
下列編譯器優化隨附 #import 指示詞:
標頭檔在建立時會獲得與類型程式庫相同的時間戳記。
處理 #import 時 ,編譯器會先檢查標頭是否存在且為最新狀態。 如果是,則不需要重新建立。
#import 指示詞也會參與最少的重建,而且可以放在先行編譯標頭檔中。 如需詳細資訊,請參閱 建立先行編譯標頭檔 。
主要類型程式庫標頭檔
主要類型程式庫標頭檔包含七個區段:
標題重複使用區段:包含註解、COMDEF.H 的
#include
陳述式 (會定義標題中使用的一些標準巨集),以及其他設定資訊。向前參考和 typedef:包含結構宣告,例如
struct IMyInterface
和 Typedef。智慧型指標宣告:範本類別
_com_ptr_t
是智慧型指標。 它會封裝介面指標,並不需要呼叫AddRef
、Release
和QueryInterface
函式。 它也會在CoCreateInstance
建立新的 COM 物件時隱藏呼叫。 本節會使用巨集式_COM_SMARTPTR_TYPEDEF
,將 COM 介面的 typedefs 建立為_com_ptr_t 樣板類別的 範本特製化。 例如,針對 介面IMyInterface
,則為 。TLH 檔案將包含:_COM_SMARTPTR_TYPEDEF(IMyInterface, __uuidof(IMyInterface));
編譯器將展開為:
typedef _com_ptr_t<_com_IIID<IMyInterface, __uuidof(IMyInterface)> > IMyInterfacePtr;
然後就可以將類型
IMyInterfacePtr
用來取代原始介面指標IMyInterface*
。 因此,不需要呼叫各種IUnknown
成員函式Typeinfo 宣告:主要包含類別定義和其他專案,公開 所
ITypeLib:GetTypeInfo
傳回的個別 typeinfo 專案。 在本節中,類型程式庫中的每個 typeinfo 會反映在相依於TYPEKIND
資訊之表單的標頭中。選擇性舊樣式 GUID 定義:包含具名 GUID 常數的初始化。 這些名稱的格式
CLSID_CoClass
為 和IID_Interface
,類似于 MIDL 編譯器所產生的名稱。次要類型程式庫標頭的
#include
陳述式。頁尾重複使用區段:目前包含
#pragma pack(pop)
。
除了標題樣板和頁尾樣板區段之外,所有區段都會以命名空間括住,其名稱是由 library
原始 IDL 檔案中的 語句所指定。 您可以使用命名空間名稱的明確限定性,從類型程式庫標頭使用名稱。 或者,您可以包含下列語句:
using namespace MyLib;
緊接在 原始程式碼中的 #import 語句之後。
您可以使用 #import 指示詞的 no_namespace ) 屬性來隱藏 命名空間。 不過,隱藏命名空間可能導致名稱衝突。 命名空間也可以由 rename_namespace 屬性重新命名。
編譯器提供目前處理之類型程式庫所需的任何類型程式庫相依性的完整路徑。 路徑會以註解的形式寫入類型程式庫標頭 (.TLH),編譯器為每個處理過的類型程式庫產生此標頭。
如果類型程式庫包含定義於其他類型程式庫之類型的參考,則 .TLH 檔案會包含下列排序的註解:
//
// Cross-referenced type libraries:
//
// #import "c:\path\typelib0.tlb"
//
#import 批註中 的實際檔案名是跨參考型別程式庫的完整路徑,儲存在登錄中。 如果您遇到因遺漏類型定義所造成的錯誤,請檢查 前端的批註。TLH 查看哪些相依類型程式庫可能需要先匯入。 編譯 .TLI 檔案時,可能發生的錯誤為語法錯誤 (例如,C2143、C2146、C2321)、C2501 (遺漏 decl 指定名稱) 或 C2433 (資料宣告不允許「內嵌」)。
若要解決相依性錯誤,請判斷系統標頭未提供哪些相依性批註,然後在相依類型程式庫的 #import 指示詞之前 ,于某個時間點提供 #import 指示詞。
#import 屬性
#import 可以選擇性地包含一或多個屬性。 這些屬性會指示編譯器修改類型程式庫標頭的內容。 反斜線 ( \ ) 符號可用來在單 一 #import 語句中包含其他行。 例如:
#import "test.lib" no_namespace \
rename("OldName", "NewName")
如需詳細資訊,請參閱 #import 屬性 。
END C++ 特定
另請參閱
意見反映
https://aka.ms/ContentUserFeedback。
即將推出:我們會在 2024 年淘汰 GitHub 問題,並以全新的意見反應系統取代並作為內容意見反應的渠道。 如需更多資訊,請參閱:提交及檢視以下的意見反映: