MFC(C++)App/DLL

① MFCDllDialog.dll のロジック

MFCDllDialog.h

MFCDllDialog.cpp

DialogExample.h

リソースファイル(resource.h と .rc)

resource.h

.rc ファイル:

② MFCApplication.exe のロジック

MainForm.cpp

MainForm.h

resource.h

.rc ファイル

MainForm.cpp のイベント登録

重要なポイント

  1. DLLの読み込みと解放
    • LoadLibrary を使って動的にDLLを読み込み、FreeLibrary で解放します。
    • 関数ポインタ (GetProcAddress) を使って MFCDllDialogShow を呼び出します。
  2. DLLとアプリケーションの連携
    • DLL内の MFCDllDialogShow は、MFC ダイアログを表示する関数。
    • アプリケーション側でDLLを動的に読み込み、必要なときだけ関数を実行します。
  3. エラーハンドリング
    • DLLが見つからない場合や、関数が取得できない場合にエラーメッセージを表示する処理を追加しています。

ヘッダーファイルをエクスポート側とインポート側で共通利用する場合

静的リンクと動的リンクの違い

  1. 静的リンク
    • ライブラリファイル (.lib) とヘッダーファイル (.h) をアプリケーションに組み込む形です。
    • 実行時に外部DLLをロードする必要がありません。すべてが実行ファイルに埋め込まれます。
    • リンカ設定で .lib ファイルを指定します。
  2. 動的リンク
    • 実行時にDLLファイル(例:example.dll)を読み込みます。
    • リンカはDLLに対応するインポートライブラリ (.lib) を参照するか、動的に LoadLibrary でDLLをロードします。
    • 実行ファイル自体はDLLが必要で、DLLが見つからないとエラーになります。

ンカ設定に必要な項目

静的リンク

  • .h ファイルと .lib ファイルをプロジェクトに追加します。
  • リンカ設定で .lib を指定します。
    • 設定方法(Visual Studioの場合):
      1. プロジェクトのプロパティを開く。
      2. リンカー > 入力 > 追加の依存ファイル.lib ファイルを指定します。
  • __declspec(dllexport)__declspec(dllimport) の役割
    • 静的リンクでは、DLL自体をロードしませんが、.lib を通じてDLL内のシンボルを参照します。
    • __declspec(dllimport) を指定すると、コンパイラがインポートライブラリの記述をもとに効率的にリンクを行います。

動的リンク

  • 実行時に LoadLibraryGetProcAddress を使用してDLLを読み込みます。
  • .lib ファイルは不要です。
  • リンカ設定は不要で、DLLを直接動的にロードします。

静的リンクの場合のコード例

以下は、静的リンクの場合のコード例です。

エクスポート側(DLL側)

#pragma once

#ifdef MYLIB_EXPORTS
#define MYLIB_API __declspec(dllexport) // DLLをエクスポート
#else
#define MYLIB_API __declspec(dllimport) // DLLをインポート
#endif

extern "C" MYLIB_API int Add(int a, int b);

MyLib.cpp

#include "MyLib.h"

extern "C" MYLIB_API int Add(int a, int b) {
return a + b;
}

ビルドすると、以下のファイルが生成されます:

  • MyLib.dll(実行時に使用)
  • MyLib.lib(静的リンク時に使用)

インポート側(アプリケーション側)

Main.cpp

#include <iostream>
#include "MyLib.h" // DLLのヘッダーファイル

int main() {
int result = Add(3, 5); // 静的リンクでAdd関数を使用
std::cout << "Result: " << result << std::endl;
return 0;
}

プロジェクト設定

  • リンカー > 入力 > 追加の依存ファイルMyLib.lib を指定します。

動的リンクの場合のコード例

エクスポート側(DLL側)

同じです。__declspec(dllexport) を使います。

インポート側(アプリケーション側)

Main.cpp

#include <iostream>
#include <Windows.h>

typedef int (*AddFunc)(int, int);

int main() {
// DLLをロード
HMODULE hModule = LoadLibrary("MyLib.dll");
if (!hModule) {
std::cerr << "DLLが見つかりません" << std::endl;
return 1;
}

// 関数ポインタを取得
AddFunc Add = (AddFunc)GetProcAddress(hModule, "Add");
if (!Add) {
std::cerr << "Add関数が見つかりません" << std::endl;
FreeLibrary(hModule);
return 1;
}

// 関数を使用
int result = Add(3, 5);
std::cout << "Result: " << result << std::endl;

// DLLを解放
FreeLibrary(hModule);
return 0;
}

まとめ

  • 静的リンクでは、.lib ファイルを使用し、リンカで設定を行います。ヘッダーファイルには __declspec(dllimport) が必要です。
  • 動的リンクでは、LoadLibraryGetProcAddress を使用し、__declspec(dllimport) は不要です。
  • 静的リンクと動的リンクの違いを正確に把握し、用途に応じて使い分ける必要があります。