回答:
次の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 "^サブシステム" サブシステム00000003(Windows CUI) C:\ test> _
これは、リンカがデフォルトで実行可能なコンソールサブシステムを生成したことを意味します。ファイルヘッダーのサブシステム値は、プログラムに必要なサービスをWindowsに通知します。この場合、コンソールシステムでは、プログラムにコンソールウィンドウが必要です。
これにより、コマンドインタープリターはプログラムが完了するまで待機します。
次に、GUIサブシステムを使用してビルドします。これは、プログラムがコンソールウィンドウを必要としないことを意味します。
C:\ test> gnuc x.cpp -mwindows C:\ test> objdump -x a.exe | findstr / i "^サブシステム" サブシステム00000002(Windows GUI) C:\ test> _
-mwindows
フラグは半文書化されているだけですが、うまくいけばこれまでのところ問題ありません。
セミドキュメント化されたフラグなしでビルドする場合は、必要なサブシステム値をリンカーに具体的に通知する必要があります。その場合、一部のWindows APIインポートライブラリは、一般的に明示的に指定する必要があります。
C:\ test> gnuc x.cpp -Wl、-subsystem、windows C:\ test> objdump -x a.exe | findstr / i "^サブシステム" サブシステム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 "サブシステム"を見つける| / i "Windows"を見つける 3サブシステム(Windows CUI) C:\ test> _
ただし、GUIサブシステムとしてのMicrosoftのツールチェーンの構築では、デフォルトでは機能しません。
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
。
しかし、それを修正するのは大したことではありません。
あなたがしなければならないのは、Microsoftのリンカーにどのエントリーポイントを使用するか、つまりmainCRTStartup
、標準を呼び出すを伝えることだけですmain
:
C:\ test> msvc x.cpp user32.lib / link / subsystem:windows / entry:mainCRTStartup x.cpp C:\ test> dumpbin / headers x.exe | / i "サブシステム"を見つける| / i "Windows"を見つける 2サブシステム(Windows GUI) C:\ test> _
問題ありませんが、とても退屈です。また、難解で隠されているため、ほとんどの場合Microsoftのデフォルトではない非標準ツールを使用するほとんどのWindowsプログラマーは、それについてさえ知らず、Windows GUIサブシステムプログラムは標準ではWinMain
なく非標準である必要があると誤って考えています。main
。ちなみに、コンパイラはC ++ 0xでこれに問題があります。コンパイラは、それが自立型かホスト型かを宣伝する必要があるためです(ホスト型の場合、標準をサポートする必要がありますmain
)。
とにかく、それがg ++ がWinMain
欠落について文句を言う理由です。これは、MicrosoftのツールがデフォルトでGUIサブシステムプログラムに必要とする愚かな非標準の起動関数です。
ただし、上記のように、main
GUIサブシステムプログラムであっても、g ++は標準で問題ありません。
では、何が問題になるのでしょうか?
まあ、あなたはおそらく欠落していmain
ます。そしておそらくあなたも(適切な)何も持っていませんWinMain
!そして、g ++はmain
(そのような)を検索した後、およびMicrosoftの非標準WinMain
(そのような)を検索した後、後者が欠落していると報告します。
空のソースを使用したテスト:
C:\ test>タイプnul> y.cpp C:\ test> gnuc y.cpp -mwindows c:/プログラムファイル/mingw/bin/../lib/gcc/mingw32/4.4.1/../../../libmingw32.a(main.o):main.c:(.text+0xd2 ):未定義の参照 「WinMain @ 16」にCE collect2:ldが1つの終了ステータスを返しました C:\ test> _
main
またはを定義するかWinMain
、関連ファイルがプロジェクトに含まれていることを確認します。乾杯、
main
またはを定義するとはどういう意味winmain
ですか?ありがとう
Cheersとhthによる上記の投稿をまとめます。-Alf、あなたが持っているmain()
かWinMain()
定義していることを確認してください、そしてg ++は正しいことをするべきです。
私の問題は、それmain()
が名前空間の中で誤って定義されたことでした。
SDLでアプリケーションをコンパイルしているときにこのエラーが発生しました。これは、SDLがSDL_main.hに独自のメイン関数を定義しているために発生しました。SDLがメイン関数を定義しないようにするには、SDL.hヘッダーが含まれる前にSDL_MAIN_HANDLEDマクロを定義する必要があります。
ビルドする前に.cファイルを保存してみてください。私はあなたのコンピュータがその中に情報のないファイルへのパスを参照していると思います。
-Cプロジェクトのビルド時に同様の問題がありました
すべてのファイルがプロジェクトに含まれていることを確認します。
cLionを更新した後、同じエラーがポップアップ表示されました。何時間もいじくり回した後、自分のファイルの1つがプロジェクトターゲットに含まれていないことに気付きました。アクティブなプロジェクトに再度追加した後、未定義のwinmain16への参照の取得を停止し、コードをコンパイルしました。
編集:IDE内でビルド設定を確認することも価値があります。
(このエラーが最近IDEを更新したことに関連しているかどうかは不明です-原因であるか、単に相関している可能性があります。その要因についての洞察を自由にコメントしてください!)
All you have to do is to tell Microsoft's linker which entry point to use, namely mainCRTStartup, which calls standard main
。Eclipse CDT
コマンドラインを使用していないので、それを行う方法はありますか?ありがとう