DLL に関してよく寄せられる質問

MFC DLL から複数のスレッドを作成できますか。

初期化中を除き、MFC DLL では、TlsAlloc などの Win32 スレッド ローカル ストレージ (TLS) 関数を使用してスレッド ローカル ストレージを割り当てる限り、複数のスレッドを安全に作成できます。 ただし、MFC DLL で __declspec(thread) を使用してスレッド ローカル ストレージを割り当てる場合、クライアント アプリケーションは暗黙的に DLL にリンクされている必要があります。 クライアント アプリケーションが明示的に DLL にリンクされている場合、LoadLibrary を呼び出しても DLL は正常に読み込まれません。 DLL のスレッド ローカル変数の詳細については、「thread」を参照してください。

起動中に新しい MFC スレッドを作成する MFC DLL は、アプリケーションによって読み込まれると応答を停止します。 これには、次の内部で AfxBeginThread または CWinThread::CreateThread を呼び出してスレッドを作成する場合も含まれます。

  • 標準 MFC DLL 内の CWinApp 派生オブジェクトの InitInstance

  • 標準 MFC DLL 内の指定された DllMain または RawDllMain 関数。

  • MFC 拡張 DLL 内の指定された DllMain または RawDllMain 関数。

マルチスレッド アプリケーションでは異なるスレッドで MFC DLL にアクセスできますか。

マルチスレッド アプリケーションでは、別のスレッドから、MFC および MFC 拡張 DLL に動的にリンクされる標準 MFC DLL にアクセスできます。 アプリケーションでは、そのアプリケーション内で作成された複数のスレッドから、MFC に静的にリンクされた標準 MFC DLL にアクセスできます。

MFC DLL 内で使用できない MFC クラスまたは関数はありますか。

拡張 DLL では、クライアント アプリケーションの CWinApp 派生クラスが使用されます。 それらが独自の CWinApp 派生クラスを持つことはできません。

標準 MFC DLL には、MFC アプリケーションと同様に、CWinApp 派生クラスと、そのアプリケーション クラスの 1 つのオブジェクトが必要です。 アプリケーションの CWinApp オブジェクトとは異なり、DLL の CWinApp オブジェクトにはメイン メッセージ ポンプがありません。

CWinApp::Run メカニズムは DLL に適用されないため、アプリケーションにはメイン メッセージ ポンプがあることに注意してください。 DLL がモードレス ダイアログ ボックスを開く場合、または独自のメイン フレーム ウィンドウがある場合、アプリケーションのメイン メッセージ ポンプでは、DLL によってエクスポートされたルーチンを呼び出し、次に DLL のアプリケーション オブジェクトの CWinApp::PreTranslateMessage メンバー関数を呼び出す必要があります。

読み込み時にクライアント アプリケーションのパフォーマンスを向上するための最適化技法

使用する DLL が MFC に静的にリンクされている標準 MFC DLL である場合、それを MFC に動的にリンクされている標準 MFC DLL に変更すると、ファイル サイズが小さくなります。

DLL にエクスポートされた関数が多数ある場合は、.def ファイルを使用して (__declspec(dllexport) を使用するのではなく) 関数をエクスポートし、エクスポートされた各関数に対して .def ファイルの NONAME 属性を使用します。 NONAME 属性を指定すると、関数名ではなく序数値だけが DLL のエクスポート テーブルに格納され、ファイル サイズが小さくなります。

アプリケーションに暗黙的にリンクされる DLL は、アプリケーションの読み込み時に読み込まれます。 読み込み時のパフォーマンスを向上させるには、その DLL を複数の DLL に分割してみてください。 呼び出し元のアプリケーションが読み込みの直後に必要とするすべての関数を 1 つの DLL に配置し、呼び出し元のアプリケーションがその DLL に暗黙的にリンクするようにします。 呼び出し元のアプリケーションがすぐには必要としないその他の関数を別の DLL に配置し、アプリケーションがその DLL に明示的にリンクするようにします。 詳細については、実行可能ファイルと DLL のリンクに関する記事をご覧ください。

標準 MFC DLL でメモリ リークが発生しましたが、自分のコードは正常に見えます。 メモリ リークを検出するにはどうすればよいですか。

メモリ リークの考えられる原因の 1 つは、メッセージ ハンドラー関数内で使用される一時オブジェクトが MFC によって作成されることです。 MFC アプリケーションでは、メッセージの処理の間に呼び出される CWinApp::OnIdle() 関数内で、これらの一時オブジェクトが自動的にクリーンアップされます。 しかし、MFC ダイナミックリンク ライブラリ (DLL) では、OnIdle() 関数は自動的には呼び出されません。 その結果、一時オブジェクトが自動的にクリーンアップされません。 一時オブジェクトをクリーンアップするには、DLL で定期的に OnIdle(1) を明示的に呼び出す必要があります。