【Visual Studio】リンカーの設定一つでたった 11行 のプログラムがコンパイルできなかった話


はじめに

タイトル通りです。
僕がまだ Visual Studio に慣れていない時、空のプロジェクト を新規作成して、以下のようなプログラムを書きました。

WinMain.cpp
#include <Windows.h>

int WINAPI WinMain(
	HINSTANCE hInst,
	HINSTANCE hPreInst,
	LPSTR lpCmdLine,
	int nCmdShow
) {
	MessageBox(NULL, L"Hello World", L"Test", MB_OK);
	return 0;
}

実行しようと思い、

をクリック。でもね、

っていうエラーが出てきました。皆さんも 1回 は見たことあるんじゃないでしょうか?どうやらこれ、リンカーの設定のせいらしくて、エントリポイント関数の設定が WinMain じゃないからこうなるらしいです。
でもこれエラーコードもよくわからないですよね。初心者殺しです。

エントリポイント関数ってなんぞや?

エントリーポイントとは、プログラムを実行するうえで、プログラムやサブルーチンの実行を開始する場所のこと。プログラム全体のエントリーポイントとなる場所を含むルーチンがメインルーチンである。 (Wikipedia)

つまり、main 関数とかそういう、プログラムの中で最初に呼び出される関数 のことです。
エントリポイント関数の設定は、エントリポイント関数が main 関数か、WinMain 関数かどうかっていうものです。(EFI アプリケーション とかそういうものもある)

問題の設定

これは、リンカーの設定を変更するだけで解決します。

まずは、Visual Studio 上部の デバッグ(D) をクリックします。

そしたら、赤枠内の [プロジェクト名] のデバック プロパティ をクリックしてください。

こんな画面になると思うので、リンカータブを展開します。

色々でてくるので、赤枠内の システム をクリックします。
スクリーンショット 2022-03-17 083142.png
そしたら、サブシステムコンソール (/SUBSYSTEM:CONSOLE) から、設定なし もしくは Windows (/SUBSYSTEM:WINDOWS) に変更します。どっちを選んでも特に問題は無いと思います。
変更したら、OK をクリックしてエディターに戻ります。

すると、エントリポイント関数が WinMain のプログラムはコンパイルできると思います。
Windows (/SUBSYSTEM:WINDOWS) に設定した人は、main 関数がエントリポイント関数となるプログラムはコンパイルできなくなります。

さいごに

この設定、初心者とか使い始めたての方には非常に不親切なものだと思います。エラーコードも意味不明ですね。
この記事を読んで解決してくれたらうれしいです。

他にもプロジェクトを作成するとき 空のプロジェクト ではなく、Windows デスクトップ ウィザード というものを選択してでもできますが、上記の設定を知っておけば、後から、エントリポイント関数を変更するとき等にも役に立つので、こう説明されていただきました。