#import ディレクティブ (C++)
C++ 固有の仕様
タイプ ライブラリからの情報を組み込むために使用します。 タイプ ライブラリの内容は、ほとんどが COM インターフェイスを記述した C++ クラスに変換されます。
#import "filename" [attributes]
#import <filename> [attributes]
パラメーター
filename
インポートするタイプ ライブラリ ファイルを指定します。 filename は次のいずれかになります。.olb、.tlb、.dll ファイルなど、タイプ ライブラリを含むファイルの名前。 キーワード file: は、各ファイル名の前に記述できます。
タイプ ライブラリのコントロールの progid。 キーワード progid: は、各 progid 名の前に記述できます。 次に例を示します。
#import "progid:my.prog.id.1.5"
progid の詳細については、「ローカリゼーション ID とバージョン番号の指定」を参照してください。
64 ビット オペレーティング システム上でクロス コンパイラによりコンパイルを実行した場合、コンパイラは 32 ビット レジストリ ハイブのみ読み取り可能になることに注意してください。 ネイティブ 64 ビット コンパイラを使用して、64 ビットのタイプ ライブラリをビルドおよび登録した方がよい場合があります。
タイプ ライブラリのライブラリ ID。 キーワード libid: は、各ライブラリ ID の前に記述できます。 次に例を示します。
#import "libid:12341234-1234-1234-1234-123412341234" version("4.0") lcid("9")
バージョンまたは lcid を指定しない場合、progid: に適用される規則が libid: にも適用されます。
実行可能 (.exe) ファイル。
タイプ ライブラリのリソース (.ocx など) を含むライブラリ (.dll) ファイル。
タイプ ライブラリを保持する複合ドキュメント。
LoadTypeLib API によって認識できる他のファイル形式。
attributes
1 つ以上の #import 属性。 複数の属性を指定するときは、空白またはコンマで区切ります。 次に例を示します。#import "..\drawctl\drawctl.tlb" no_namespace, raw_interfaces_only
または
#import "..\drawctl\drawctl.tlb" no_namespace raw_interfaces_only
解説
ファイル名の検索順序
filename はディレクトリの指定の後に指定します (省略可能)。 そのファイル名は既存のファイルの名前であることが必要です。 2 つの構文形式間の違いは、パスの指定が不完全であるときに、プリプロセッサがタイプ ライブラリ ファイルを検索する順序です。
構文形式 |
動作 |
---|---|
引用符形式 |
#import ステートメントを含むファイルのディレクトリから最初にタイプ ライブラリ ファイルを探し、次に、そのファイルを含む (#include) すべてのファイルのディレクトリを探すようにプリプロセッサに指示します。 プリプロセッサは次のパスに従って検索します。 |
山かっこ形式 |
プリプロセッサに次のパスに従ってタイプ ライブラリ ファイルを検索するように指示します。
|
ローカリゼーション ID およびバージョン番号の指定
progid を指定するときに、progid のローカリゼーション ID とバージョン番号も指定できます。 次に例を示します。
#import "progid:my.prog.id" lcid("0") version("4.0)
ローカリゼーション ID を指定しない場合、progid は、次の規則に従って選択されます。
ローカリゼーション ID が 1 つしかない場合、その ID が使用されます。
ローカリゼーション ID が複数ある場合、バージョン番号が 0、9、または 409 の最初の ID が使用されます。
ローカリゼーション ID が複数あり、それらのいずれも 0、9、または 409 ではない場合、最後の ID が使用されます。
バージョン番号を指定しない場合、最も新しいバージョンが使用されます。
インポートで作成されるヘッダー ファイル
#import は、C++ ソース コード内のタイプ ライブラリの内容を再生成する 2 つのヘッダー ファイルを作成します。 プライマリ ヘッダー ファイルは、Microsoft インターフェイス定義言語 (MIDL) コンパイラによって生成されるものと似ていますが、より多くのコードとデータがコンパイラによって生成されます。 プライマリ ヘッダー ファイルには、タイプ ライブラリと同じ基本名と .TLH 拡張子が付けられます。 セカンダリ ヘッダー ファイルには、タイプ ライブラリと同じ基本名と .TLI 拡張子が付けられます。 このファイルは、コンパイラが生成したメンバー関数の実装を格納しており、プライマリ ヘッダー ファイルにインクルード (#include) されます。
byref パラメーターを使用するディスパッチ インターフェイスのプロパティをインポートする場合、#import は関数の __declspec(property) ステートメントを生成しません。
ヘッダー ファイルは両方とも、/Fo (オブジェクト ファイルを指定) オプションで指定された出力ディレクトリに保存されます。 それらのファイルは、プライマリ ヘッダー ファイルが #include ディレクティブで指定されているように、コンパイラによって読み取られてコンパイルされます。
次のコンパイラの最適化は #import ディレクティブに含まれます。
ヘッダー ファイルは作成時にタイプ ライブラリと同じタイムスタンプが付けられます。
#import を処理するとき、コンパイラは最初にヘッダーが存在し、最新であることを確認します。 最新のヘッダーが存在する場合、再作成は不要です。
#import ディレクティブは簡易リビルド用にプリコンパイル済みヘッダー ファイル内に記述することもできます。 詳細については、「プリコンパイル済みヘッダー ファイルの作成」を参照してください。
プライマリ タイプ ライブラリ ヘッダー ファイル
プライマリ タイプ ライブラリのヘッダー ファイルは、7 つのセクションで構成されます。
見出しの定型句: コメント、COMDEF.H の #include ステートメント (ヘッダーで使用される標準マクロを定義)、およびその他のセットアップ情報で構成されます。
前方参照と typedef: struct IMyInterface や typedef のような構造体の宣言で構成されます。
スマート ポインター宣言: _com_ptr_t テンプレート クラスは、インターフェイス ポインターをカプセル化して AddRef 関数、Release 関数、QueryInterface 関数の呼び出しを不要にするスマート ポインターの実装です。 また、新しい COM オブジェクトの作成時に CoCreateInstance 呼び出しを隠します。 このセクションでは、_COM_SMARTPTR_TYPEDEF マクロ ステートメントを使用して、_com_ptr_t テンプレート クラスの特殊化のために、COM インターフェイスの typedef を行います。 たとえば、インターフェイス 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) が含まれます。
見出しの定型句およびフッターの定型セクションを除くすべてのセクションは、元の IDL ファイルの library ステートメントで名前を指定されている名前空間にあります。 名前空間名による明示的な修飾、または次のステートメントを含めることによって、タイプ ライブラリ ヘッダーの名前を使用できます。
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-specifier の欠落)、または C2433 (データ宣言子内でのインライン禁止) です。
依存関係のコメントにあるどのタイプ ライブラリがシステム ヘッダーに定義されていないかを調べた後、そのタイプ ライブラリの #import ディレクティブを、依存関係のあるタイプ ライブラリの #import ディレクティブの前に挿入して、エラーを解決する必要があります。
詳細については、サポート技術情報の「#import Wrapper Methods May Cause Access Violation (Q242527)」または「Compiler Errors When You Use #import with XML (Q269194)」を参照してください。 サポート技術情報の文書は、MSDN ライブラリ メディアまたは https://support.microsoft.com/support/ で参照できます。
#import の属性
#import には 1 つ以上の属性を含めることができます (省略可能)。 これらの属性は、コンパイラにタイプ ライブラリ ヘッダーの内容を変更するように指示します。 円記号 (\) を使用すると、単一の #import ステートメント内に行を追加できます。 次に例を示します。
#import "test.lib" no_namespace \
rename("OldName", "NewName")
詳細については、「#import の属性 (C++)」を参照してください。
END C++ 固有の仕様