北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

SDLMain.m がなんとなく嫌

SDLの勉強会に出させてもらうことになったので、インストールだけしました。ほんとインストールだけ・・・。

ところで、XCodeとかCocoaとかな環境で*1コンパイルするときは、自分で作った XXXX.c の中にmain()関数を書いて、 SDLMain.m も一緒にコンパイルして下さいって書いてるわけです。

1. You must include either SDLMain.m/.h or libSDLmain in your application, because this is the code that defines SDL's entry point.

(中略)

2. You must give your main() procedure the following prototype:

int main(int argc, char*argv[]);

Frequently Asked Questions: Mac OS X

でも、SDLMain.mの中見たら、なんとmain()関数があります。え、mainってシンボルが二つあっちゃリンカ的におかしくなるのでは??


・・・としばし考えたんですが、SDL_main.h*2の中見たら、こんなことになってます。

#if defined(__WIN32__) || \
    (defined(__MWERKS__) && !defined(__BEOS__)) || \
    defined(__MACOS__) || defined(__MACOSX__) || \
    defined(__SYMBIAN32__) || defined(QWS)

(中略)

#define main	SDL_main

(中略)

#endif /* Need to redefine main()? */

プラットフォームによってはmain() をSDL_main に書き換えちゃうのね。ほへー。SDLMain.mの中は、実はこうです。

#ifdef main
#  undef main
#endif

/* Main entry point to executable - should *not* be SDL_main! */
int main (int argc, char **argv)
{
(以下略)
}

ああ、マクロをundefしてるのね。なんかずるい。ちなみにSDLはこの仕組みを使って、プラットフォームごとの初期化処理をうまく吸収しているようです。特に変な初期化が要らないプラットフォームでは、main/dummy/SDL_dummy_main.cを使っています。

/* Include the SDL main definition header */
#include "SDL_main.h"

#ifdef main
#undef main
int main(int argc, char *argv[])
{
	return(SDL_main(argc, argv));
}
#else
/* Nothing to do on this platform */
#endif

winだったら、main/win32/SDL_win32_main.cとか見ちゃって下さい。なにやら色色してから、SDL_main(自分で書いたmain関数)を呼び出してくれます。


でも、他のプラットフォームではうまく隠蔽して単にmain関数書くだけでコンパイルできるのに、なんでOS Xはこの泥臭い処理がSDLMain.mと言う形で見えてるのかはちょっと謎。.frameworkにはmainシンボルが入れられないとか、そういう事情があるんでしょうかね。

*1:.frameworkとしてインストールしたときは、ですね。

*2:OS X用のSDLMain.hとは別物なので注意