次の方法で共有


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

更新 : 2007 年 11 月

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 モジュールの状態データの管理