DLL のエクスポート関数のエントリ ポイント

DLL のエクスポート関数の場合は、DLL モジュールから呼び出し元アプリケーションの DLL に切り替えるときに、AFX_MANAGE_STATE マクロを使用して、適切なグローバル状態を維持します。

このマクロを呼び出すと、モジュールのグローバル データが含まれている AFX_MODULE_STATE 構造体へのポインターである pModuleState が、関数のあるスコープの残り部分に対して有効なモジュール状態として設定されます。 マクロが含まれているスコープから出ると、以前の有効なモジュール状態が自動的に復元されます。

この切り替えは、スタックに AFX_MODULE_STATE クラスのインスタンスを構築することで実現されます。 このクラスは、コンストラクターで現在のモジュール状態へのポインターを取得し、メンバー変数に格納します。その後、pModuleState を新しい有効なモジュール状態として設定します。 このクラスは、デストラクターでは、メンバー変数に格納されているポインターを有効なモジュール状態として復元します。

DLL 内のダイアログ ボックスを起動する関数など、エクスポート関数がある場合は、関数の先頭に次のコードを追加する必要があります。

AFX_MANAGE_STATE(AfxGetStaticModuleState())

これにより、現在のスコープの終わりまで、現在のモジュールの状態が AfxGetStaticModuleState から返された状態と交換されます。

AFX_MANAGE_STATE マクロを使用しない場合、DLL 内のリソースに関する問題が発生します。 既定では、MFC はメイン アプリケーションのリソース ハンドルを使用して、リソース テンプレートを読み込みます。 このテンプレートは、実際には DLL に格納されています。 根本原因は、MFC のモジュール状態情報が AFX_MANAGE_STATE マクロによって切り替えられていないことです。 リソース ハンドルは、MFC のモジュール状態から回復されます。 モジュール状態を切り替えないと、正しくないリソース ハンドルが使用されます。

AFX_MANAGE_STATE は、DLL 内のすべての関数に挿入する必要はありません。 たとえば、InitInstance は、AFX_MANAGE_STATE なしで、アプリケーション内の MFC コードによって呼び出すことができます。MFC が自動的に、InitInstance の前にモジュール状態をシフトし、InitInstance から戻った後で元のモジュール状態に戻すためです。 すべてのメッセージマップ ハンドラーでも同様です。 通常の MFC DLL では、実際にはメッセージをルーティングする前にモジュール状態を自動的に切り替える特別なマスター ウィンドウ プロシージャがあります。

関連項目

MFC モジュールの状態データの管理