MinGW コンパイラを利用する Windows プログラミング演習の注意点
MinGW は, GNU プロジェクトにより提供されている, フリーウェアである UNIX 互換のコンパイラ群である. プログラムには Windows 用ライブラリも含まれているので, Windows 用プログラムを自作することもできる.ただし, SDK が含まれていないので, MinGW 単体で大規模なプロジェクトに当たるのは難しい.
通関士試験が終了したので, 空いた時間を使って Windows プログラムの作成を勉強しているところである. 教材は猫でもわかる Windows プログラミング.
早速, ウィンドウを作成するプログラムソースコードを書いて g++ コンパイラに読み込ませたところ, 次のようなエラーが出た.
error: cast from ‘LPSTR {aka char*}’ to ‘WORD {aka short unsigned int}’ loses precision [-fpermissive]
これは, 「LPSTR 型 (内部的には文字型変数を指すポインタ型) の変数を WORD 型 (内部的には短精度整数型) に変換すると桁落ちします」と訳せばよいだろうか. C 言語 や C++ 言語では, 変数の桁数が小さくなるような型変換は (通常であれば) 認めない仕様なので, コンパイラがエラーを出すようだ. なお, 筆者の環境では、文字型変数を指すポインタ型変数は 4 Byte, 短精度整数型は 2 Byte の変数となっている.
これを解決する手段を探っていたところ, MAKEINTRESOURCE
マクロを再定義することで解決する方法が見つかったのでメモとして残しておく.
#include <windows.h> #if defined(__MINGW32__) # undef MAKEINTRESOURCE # define MAKEINTRESOURCE(i) ((LPSTR)((ULONG_PTR)(i))) #endif /* defined(__MINGW32__) */
これは, MinGW コンパイラを使っているときに限り MAKEINTRESOURCE マクロを書き換えようというものである. MinGW を使う以上は機種 (コンパイラ、ソースコードを含む) に依存しないようにプログラムを書くのが本来の礼儀だろうが, 出来上がるものが Windows 専用なので目をつぶることにする.
そのあとのコンパイルでも苦戦. g++ のコンパイルオプションに -mwindows
を付加することはすぐに分かったのだが, 出来上がったプログラムを実行すると次のエラーメッセージが出た.
コンピュータに libgcc_s_sjlj-1.dll がないため、プログラムを開始できません。この問題を解決するには、プログラムを再インストールしてみてください。
つまり, DLL が不足しているからプログラムを実行できないというエラーである. 当然, libgcc_s_sjlj-1.dll はWindows 標準システムに組み込まれているものではないのでこのままではプログラムを実行できない (DLL 自体は MinGW の中に入っている). かといって, システムフォルダに Microsoft の署名がない DLL を直接コピーするのもいろいろと問題があるので, 実行ファイルにライブラリを組み込む (静的リンク) ようなコンパイルオプションを指定した.
以上をまとめると, プログラムソースでは MAKEINTRESOURCE マクロの定義を書き直し, コンパイラに与えるコマンドをg++ -static -mwindows -o (実行ファイル名) (ソースコードファイル名)
とすればよいということになる. コンパイラのオプションには好みで -Wall
(細かいレベルで警告を出す), -s
(デバッグ情報などを削除し実行ファイルのサイズを小さくする), -On
(最適化を施し, 実行速度を上げたり実行ファイルのサイズを小さくしたりする. n は最適化レベル. 2 がよく使われる.) などを付加するのもよい.
次の問題は Shift JIS (正確には CP932) が FSS ではない文字コードであることに起因するものになりそうだが… それはもう少し学習を進めてから考えよう. MinGW (32 bit) には iconv を組み込まれているため g++ のオプションに文字コードにまつわるもの を付加すればいい話だが, MinGW (64 bit) には iconv が標準で組み込まれていないので一工夫が必要になりそうだ.