gcc -nostartfiles その5

gcc で -nostartfiles オプションを付けて C ソースコードをコンパイル&リンクすると、エントリポイントが必ず WinMain ではなくなり、コードの先頭に定義した関数になる。

#include <windows.h>
void Main() {
  int exitcode = WinMain(0, 0, "", 0);
  ExitProcess(exitcode);
}
int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cl, int cs) {
  MessageBox(NULL, TEXT("I am in WinMain"), TEXT(""), MB_OK);
  return 0;
}

そこで、先頭には、WinMain を呼ぶ関数を定義する。これによって、-nostartfiles オプションを付けようが付けまいが、コンパイル&リンクできる、互換性のあるコードにすることができる。

現在はとりあえず、WinMain にはダミーの値を渡して呼び出しているが、さらに互換性を高めるため、より適切な値を設定しよう。

まず、WinMain の第一引数には、アプリケーション自身のインスタンスハンドルを渡すようにする。

この値は、GetModuleHandle(NULL) で取得することができる。

掲示板のスレッド「Win32API質問箱 Build26」では、以下のやりとりが記録されている。

258 名前:デフォルトの名無しさん :04/12/31 21:43:00
 WinMain の引数として渡される (最初の引数の) HINSTANCE は、
 GetModuleHandle(NULL) で得られる HMODULE と同一視してもよいのでしょうか?

 MSDN を見てもそのような記述が見当たりませんでした。
 DLL であれば HINSTANCE と HMODULE は同一視できると
 ttp://msdn.microsoft.com/library/en-us/dllproc/base/dllmain.asp
 に書かれているのですが。

259 名前:デフォルトの名無しさん :04/12/31 21:46:31
 >>258
 同一視できるよ。

アプリケーション自身のインスタンスハンドルは、ウィンドウを作成する際、WNDCLASS 型の構造体メンバ hInstance に代入したり、CreateWindow に渡したりして、よく使うため、WinMain の第一引数には、ダミーではなく、GetModuleHandle(NULL) を渡しておいたほうがよいだろう。

#include <windows.h>
void Main() {
  HINSTANCE hi = GetModuleHandle(NULL);
  int exitcode = WinMain(hi, 0, "", 0);
  ExitProcess(exitcode);
}
int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cl, int cs) {
  MessageBox(NULL, TEXT("I am in WinMain"), TEXT(""), MB_OK);
  return 0;
}