SDLの設定で問題が発生した後、SDLがmainに代わるマクロを定義していることがわかりました。
#define main SDL_main
// And then
extern C_LINKAGE int SDL_main(int argc, char *argv[]);
メイン関数にargc
およびargv
パラメーターが定義されていない場合、これはコンパイルエラーを引き起こす可能性もあります。
このマクロを見ると、頭痛がします...なぜSDLはmainを再定義する必要があるのですか?さらに検索したところ、#undef main
、そしてそれを通常の方法で使用します。
これが問題です:SDLがmainを再定義する必要があるのはなぜですか?定義を解除することによる副作用はありますか?
私が気付いたのは、SDLが標準出力とエラーをファイルにリダイレクトする(そしてこの動作を望まない)ことであり、mainを未定義にするとこの動作は停止します。
Windowsアプリケーションを作成している場合でも、
main()
ではなくWinMain()
を使用する必要があります。SDLは、メインコードを呼び出す前にSDL初期化を実行するWinMain()
のバージョンを提供するためです。何らかの理由で
WinMain()
を使用する必要がある場合は、src/main/win32/SDL_main.c
のSDLソースコードを調べて、WinMain()
関数でどのような初期化を行う必要があるかを確認して、SDLが正しく機能するようにします。
SDLは初期化を必要とするため、「main」関数を呼び出す前に初期化を実行する独自のmain
関数を挿入します。この関数は、実際のmain
関数と競合しないように、SDL_main
に名前を変更します。 FAQに記載されているように、main
関数は次の形式でなければなりません。
int main(int argc, char* argv[])
これは奇妙な慣行だと私は同意しますが、プラットフォームに大きく依存しますが、これが合理的な解決策である状況があります。プラットフォームによってエントリポイントが異なることを考慮してください。 Windowsは通常WinMain、Linuxはメインであり、AndroidはJavaで発生します。WinRTはC++/CX拡張を使用します。プログラムのエントリポイントとAPIはプラットフォーム固有であり、SDLはこれに対処する手間を省くことができます。Windowsのみを対象としていて、SDLがWIN32 APIでの作業の手間を省くためだけにある場合、それは必要ないかもしれません。しかし、デスクトップを超える場合は、私の意見ではそれが役に立つと思います。