MinGWによる共有ライブラリの作成と動的リンク

MinGW g++ を使った共有ライブラリ(DLL)の作成方法と動的リンクについて紹介します。動的リンクとは、実行時に実行ファイルとライブラリをリンクすることです。また、動的リンクには明示的リンクと暗黙的リンクがあり、明示的リンクでは DLL を呼び出す関数の中で DLL のファイル名を指定しますが、暗黙的リンクでは指定しません。


共有ライブラリ(DLL)の作成

まず、下記のように example.cpp を作成します。

example.cpp


extern "C" __declspec(dllexport) int __stdcall add(int x, int y) {
  return x + y;
}

extern "C" __declspec(dllexport) int __stdcall mul(int x, int y) {
  return x * y;
}

注)__declspec(dllexport) で エクスポートする関数を指定します。

example.cpp があるフォルダでバッチファイル dll.bat を実行すると、DLL が生成されます。
__stdcall の詳細については、Stdcall and DLL tools of MSVC and MinGW を御覧ください。

dll.bat


set path=C:\MinGW\bin
g++ -shared -Wl,--kill-at example.cpp -o example.dll
strip example.dll


実行ファイル(EXE)の作成(明示的リンク)

明示的リンク用のプログラム explicit.cpp を作成します。このプログラムには、DLL のファイル名 example.dll が指定されています。

explicit.cpp


#include <iostream>
#include <windows.h>

typedef int (*Add)(int, int);
typedef int (*Mul)(int, int);

int main() {
  HMODULE hModule = LoadLibrary("example.dll");
  Add add = (Add)GetProcAddress(hModule, "add");
  Mul mul = (Mul)GetProcAddress(hModule, "mul");
  std::cout << add(1, 1) << std::endl;
  std::cout << mul(1, 1) << std::endl;
  FreeLibrary(hModule);
}

explicit.cpp があるフォルダでバッチファイル explicit.bat を実行すると、実行ファイル caller.exe が生成されます。

explicit.bat


set path=C:\MinGW\bin
g++ explicit.cpp -o caller.exe
strip caller.exe


実行ファイル(EXE)の作成(暗黙的リンク)

暗黙的リンク用のプログラム implicit.cpp を作成します。このプログラムには、DLL のファイル名 example.dll は指定されていません。

implicit.cpp


#include <iostream>

extern "C" __declspec(dllimport) int add(int, int);
extern "C" __declspec(dllimport) int mul(int, int);

int main() {
  std::cout << add(1, 1) << std::endl;
  std::cout << mul(1, 1) << std::endl;
}

注)__declspec(dllimport) はなくても構いません。

implicit.cpp と example.dll があるフォルダでバッチファイル implicit.bat を実行すると、実行ファイル caller.exe が生成されます。コマンドの中にある -lexample は example.dll のことです。
今回のやり方では LIB ファイル(インポートライブラリ)を使っていませんが、その代わりに DLL ファイルを使っています。
明示的リンクに比べ暗黙的リンクの方がプログラムを簡潔に記述できるので、通常は暗黙的リンクが用いられます。

implicit.bat


set path=C:\MinGW\bin
g++ implicit.cpp -L. -lexample -o caller.exe
strip caller.exe


EXEの実行

example.dll をパスが通っているフォルダか caller.exe があるフォルダに入れ、caller.exe があるフォルダでバッチファイル run.bat を実行して下さい。尚、実行時に libgcc_s_dw2-1.dll が必要になるので、C:\MinGW\bin にパスを通しています。

run.bat


set path=C:\MinGW\bin
caller.exe
pause


参考サイト

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中