MinGW gccでDLLをbuild

GUIツールを作る時、自分はDelphiを使った方が圧倒的に効率がいいので常にそうしているのだけれど、保守する事を考えた時に自分以外の人が使えない言語っていうのもまずいかなと思い始めたわけだが、かといってDelphiを使わないようにすると圧倒的に効率が下がってVisual Studio 爆発しろ!! などと思い始めるし、リソースを自分で書くのも阿呆らしい。
折衷案として、GUIのコントロールとモデル部分をC++で書いてDLL化し、それを呼び出すようにすれば、他の人がVisual Studio からでも使えるし、MとCはC++で書いてるから保守もそこそこできるんじゃないかという発想に至る。
しかし、DLLを作るかとなった時にVisual Studio とかなんとかいう代物は使いたくはないというどうでもいいポリシーが邪魔をする。
よって、MinGW gccでbuildする事となった。


というのは建前で、ただやった事なかったからやってみたかっただけ。


hello.h

 #if defined(__cplusplus)
 extern "C"{
 #endif
 
 void __stdcall hello(void);
 
 #if defined(__cplusplus)
 };
 #endif

hello.cpp

 #include "hello.h"
 #include <iostream>
 
 void __stdcall
 hello(void)
 {
   std::cout << "Hello World!" << std::endl;
 }

makefile

 TARGET=hello.dll
 CC=g++
 OPT=-mwindows
 
 SRC=$(shell ls *.cpp)
 OBJ=$(SRC:.cpp=.o)
 
 all: $(TARGET)
 $(TARGET): $(OBJ)
 	$(CC) $(OPT) -shared -o $@ $(OBJ) -Wl, --add-stdcall-alias
 
 .cpp.o:
	$(CC) $(OPT) -c $<

これで、"Hello World!"とコンソールに文字列を吐き出すだけの函数hello()が使えるdllが作成される。


注意点としては、

  • stdcallを付けると、函数に序数が付いてしまうので、それを消すために、リンカオプションで、--add-stdcall-aliasを付ける。
  • この実装方法だとグローバルに置かれる函数は全て参照可能。
  • DLLMain()はなくても勝手に作ってくれるらしい。