MinGWでDLLを作成して実行してみる
ファイルの内容とディレクトリ構成は以下
root
├ calc
│ ├ calc.h
│ └ calc.cpp
└ main.cpp
main.cpp
#include
#include "calc/calc.h"
int main(void)
{
printf("%d", add(1, 2));
getchar();
return 0;
}
calc.h
int add(int x, int y);
int sub(int x, int y);
calc.cpp
#include "calc.h"
int add(int x, int y)
{
return x + y;
}
int sub(int x, int y)
{
return x - y;
}
calcフォルダ内で Windows PowerShell を開いて、以下のコマンドを入力する
gcc -c calc.cpp
オブジェクトファイルができあがるのでリンクしてDLLを作成する
gcc calc.o -o a.dll -shared
-sharedを付けることでDLL形式のバイナリができあがる
出力ファイル名を指定しないと拡張子がexeになるので -o オプションをつける
次にDLLを利用するプログラムを作成する
main.cppのフォルダで Windows PowerShell を開いて、以下のコマンドを入力する
gcc -c main.cpp
main.oと先ほど作ったa.dllをリンクして実行ファイルを作成する
gcc main.o calc\a.dll
a.exeが同フォルダに作成される
実行するとa.dllが見つからないというメッセージが表示される
a.dllをcalcフォルダからa.exeがあるフォルダに移動する
再度a.exeを実行すると実行結果が表示される
注意
1.インポートライブラリ
MinGW以外のコンパイラで作成したexeでMinGW作成のDLLを使用する場合はリンク時にインポートライブラリ(.libファイル)が必要になる
インポートライブラリはDLLファイル作成の際に –out-implib オプションをつける
-Wlはリンカオプション
gcc calc.o -o a.dll -shared -Wl,--out-implib,a.lib
コマンドプロンプトでは上記で十分だが Windows PowerShellではカンマが特別な意味を持つので以下のようにする
gcc calc.o -o a.dll -shared "-Wl,--out-implib,a.lib"
2.インターフェースの公開
__declspec(dllexport) と __declspec(dllimport) を関数の前につけて公開するインターフェースを指定するのが一般的な書き方
プリプロセッサを利用すると作成時(export)と利用時(import)でヘッダを共有できるため以下のような書き方が定番となっている
#ifdef BUILDING_EXAMPLE_DLL
#define EXAMPLE_DLL __declspec(dllexport)
#else
#define EXAMPLE_DLL __declspec(dllimport)
#endif