次の方法で共有


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

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

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

この切り替えを行うには、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 の実行が終わると自動的に前のモジュール状態に戻ります。 これはどのメッセージ マップ ハンドラーの場合でも同じです。 実際には、標準 DLL には特殊なマスター ウィンドウ プロシージャがあり、このプロシージャによって、メッセージのルーティングの前にモジュール状態が自動的に切り替わります。

参照

概念

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