web-dev-qa-db-ja.com

SDLがメインマクロを定義する理由

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を未定義にするとこの動作は停止します。

39
Tibi

SDL Windows FAQ

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[])
41
James McNellis

これは奇妙な慣行だと私は同意しますが、プラットフォームに大きく依存しますが、これが合理的な解決策である状況があります。プラットフォームによってエントリポイントが異なることを考慮してください。 Windowsは通常WinMain、Linuxはメインであり、AndroidはJavaで発生します。WinRTはC++/CX拡張を使用します。プログラムのエントリポイントとAPIはプラットフォーム固有であり、SDLはこれに対処する手間を省くことができます。Windowsのみを対象としていて、SDLがWIN32 APIでの作業の手間を省くためだけにある場合、それは必要ないかもしれません。しかし、デスクトップを超える場合は、私の意見ではそれが役に立つと思います。

7
Mel