#import 指示詞 (C++)
特定C++
用來加入類型程式庫中的資訊。 類型程式庫的內容會轉換成 C++ 類別,多半是在描述 COM 介面。
語法
#import “filename” [attributes]
<#import 檔名> [屬性]
參數
filename
指定要匯入的類型程式庫。 檔案名稱可以是下列其中一種:
包含類型程式庫之檔案的名稱,例如 .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++ 特定