Eclipse CDT
を使用してプログラムをビルドしようとすると、次のメッセージが表示されます。
/mingw/lib/libmingw32.a(main.o):main.c:(.text+0x106): `WinMain @ 16への未定義の参照
何故ですか?そして、どうすればこの問題を解決できますか?
次のWindows APIレベルのプログラムを検討してください。
#define NOMINMAX
#include <windows.h>
int main()
{
MessageBox( 0, "Blah blah...", "My Windows app!", MB_SETFOREGROUND );
}
それでは、GNUツールチェーン(つまりg ++)を使用して、特別なオプションを使用せずにビルドしましょう。ここでgnuc
は、そのために使用する単なるバッチファイルです。 g ++をより標準にするオプションのみを提供します。
C:\ test> gnuc x.cpp C:\ test> objdump -x a.exe | findstr/i "^ subsystem" Subsystem 00000003(Windows CUI) C:\ test> _
これは、リンカーがデフォルトでconsoleサブシステム実行可能ファイルを生成したことを意味します。ファイルヘッダーのsubsystem値は、プログラムに必要なサービスをWindowsに通知します。この場合、コンソールシステムでは、プログラムにはコンソールウィンドウが必要です。
これにより、コマンドインタープリターはプログラムの完了を待機します。
GUIサブシステムでビルドしましょう。これは、プログラムがコンソールウィンドウを必要としないことを意味します。
C:\ test> gnuc x.cpp -mwindows C:\ test> objdump -x a.exe | findstr/i "^ subsystem" Subsystem 00000002(Windows GUI) C:\ test> _
-mwindows
フラグはまだ半文書化されていますが、これでうまくいくことを願っています。
その半文書化されたフラグなしでビルドすると、リンカに希望するサブシステム値をより具体的に伝える必要があり、いくつかのWindows APIインポートライブラリは一般に明示的に指定する必要があります。
C:\ test> gnuc x.cpp -Wl、-subsystem、windows C:\ test> objdump -x a.exe | findstr/i "^ subsystem" Subsystem 00000002(Windows GUI) C:\ test> _
GNUツールチェーンを使用すると、うまくいきました。
しかし、Microsoftツールチェーン、つまりVisual C++はどうでしょうか?
さて、コンソールサブシステムの実行可能ファイルとしてのビルドは正常に機能します。
C:\ test> msvc x.cpp user32.lib x.cpp C:\ test> dumpbin/headers x.exe |/i "サブシステム"を見つける| find/i "Windows" 3サブシステム(Windows CUI) C:\ test> _
ただし、MicrosoftのツールチェーンをGUIサブシステムとして構築すると、デフォルトでは機能しません。
C:\ test> msvc x.cpp user32.lib/link /subsystem:windows x.cpp LIBCMT.lib(wincrt0.obj):エラーLNK2019:未解決の外部シンボル_WinMain @ 16は、関数___ tmainCRTStartu p x.exeで参照されています。致命的なエラーLNK1120:1未解決の外部 C:\ test> _
技術的には、MicrosoftのリンカーはGUIサブシステムのデフォルトでは非標準であるためです。デフォルトでは、サブシステムがGUIの場合、Microsoftのリンカーは、ランタイムライブラリエントリポイントを使用します。これは、winMainCRTStartup
と呼ばれる、Microsoftの非標準WinMain
標準のmain
の代わりに。
ただし、それを修正することは大したことではありません。
する必要があるのは、使用するエントリポイント、つまり標準のmainCRTStartup
を呼び出すmain
をMicrosoftのリンカーに伝えることだけです。
C:\ test> msvc x.cpp user32.lib/link/subsystem:windows/entry:mainCRTStartup x.cpp C:\ test> dumpbin/headers x.exe |/i "サブシステム"を見つける| find/i "Windows" 2サブシステム(Windows GUI) C:\ test> _
問題ありませんが、非常に退屈です。そのため、ほとんどがMicrosoftの非標準のデフォルトツールのみを使用するほとんどのWindowsプログラマーは、それについても知らず、Windows GUIサブシステムプログラムは、非標準のWinMain
を持つ必要があると誤解します。標準main
。ちなみに、C++ 0xでは、コンパイラは、それが自立型かホスト型かをアドバタイズする必要があるため、問題が発生します(ホスト型の場合、標準のmain
をサポートする必要があります)。
とにかく、それがg ++canがWinMain
がないことについて不満を言う理由です。MicrosoftのツールがデフォルトでGUIサブシステムプログラムに必要とする愚かな非標準の起動関数です。
しかし、上記のように、g ++は、GUIサブシステムプログラムであっても、標準のmain
に問題はありません。
では、何が問題なのでしょうか?
さて、あなたはおそらくmissingmain
です。そして、おそらく(適切な)WinMain
もありません!そして、g ++は、main
(そのようなものはない)、およびMicrosoftの非標準のWinMain
(そのようなものはない)を検索した後、後者が見つからないと報告します。
空のソースでテストする:
C:\ test> type nul> y.cpp C:\ test> gnuc y.cpp -mwindows c:/ program files/mingw/bin /../ lib/gcc/mingw32/4.4.1 /../../../ libmingw32.a(main.o):main.c :(。text + 0xd2):undefined referen ce to `WinMain @ 16 ' collect2:ldが1つの終了ステータスを返しました C:\ test> _
Cheers and hthによる上記の投稿を要約します。 -アルフ、main()
またはWinMain()
が定義されていることを確認してください。g++は正しいことを行う必要があります。
私の問題は、main()
が誤って名前空間内で定義されたことです。
アプリケーションをSDLでコンパイルしているときにこのエラーが発生しました。これは、SDLがSDL_main.hで独自のメイン関数を定義していることが原因です。 SDLがメイン関数を定義しないようにするには、SDL.hヘッダーを含める前にSDL_MAIN_HANDLEDマクロを定義する必要があります。
ビルドする前に.cファイルを保存してください。あなたのコンピューターは、内部に情報のないファイルへのパスを参照していると思います。
--Cプロジェクトをビルドするときに同様の問題があった