C言語 LNK1561エラーについて解説
c言語で発生するLNK1561は、リンカーが実行開始時に呼び出すエントリーポイント、通常はmain
関数を検出できない場合に起こるエラーです。
ソースコード内にmain
関数が正しく記述されているか確認する必要があります。
エントリーポイントの定義や関数シグネチャに誤りが無いかチェックすることで、エラー解消に繋がります。
エラー発生の原因
エントリーポイント関数の未定義
エントリーポイント関数が定義されていない場合、リンカーは起動時に呼び出すべき関数を見つけられず、エラー LNK1561 を発生させます。
C言語の場合、通常は main
関数がエントリーポイントとして認識されますが、コード内に main
関数が存在しないとこのエラーが発生します。
たとえば、下記のコードはエントリーポイントが存在しないため、リンクエラーが発生します。
#include <stdio.h>
// グローバル変数の定義のみで、main 関数が定義されていない例
int globalVariable = 0;
LNK1561: エントリーポイントを定義しなければなりません
ファイルリンクの不備
エントリーポイント関数が実装されているソースファイルがビルドに含まれていない場合も、同様にリンカーはエントリーポイントを見つけられずエラーとなります。
たとえば、複数ソースファイルからビルドを行う場合、main
関数が実装されたファイルがリンクリストに含まれているかどうかを確認する必要があります。
リンク設定やプロジェクト構成のミスにより、意図したファイルが除外されるケースがあります。
関数シグネチャの誤記
エントリーポイントである main
関数のシグネチャ(返り値や引数の型、数)が誤って定義されている場合も、リンカーが正しいエントリーポイントとして認識できなくなります。
たとえば、Main
と大文字で記述したり、引数の型や順序を間違えたりすると、リンカーはこれをエントリーポイント関数と見なさないため、エラーが発生します。
正しいシグネチャは次のいずれかとなります。
- コンソールアプリケーションの場合:
リンカーの動作とエントリーポイントの役割
リンカーツールの基本動作
リンカーは、ビルドされたオブジェクトファイルやライブラリを結合し、最終的な実行形式を生成します。
その際、各アプリケーションにおいて最初に実行されるべき関数(エントリーポイント)を探し出します。
通常、リンカーは以下の名前の関数を順に検索します。
- コンソールアプリケーション:
main
またはwmain
- Windowsアプリケーション:
WinMain
またはwWinMain
- DLL:
DllMain
シグネチャやファイルリンクの状況に問題がある場合、リンカーはエントリーポイントの検出に失敗し、LNK1561エラーを発生させます。
コンソールアプリケーションの場合
コンソールアプリケーションでは、リンカーは主に main
関数または wmain
関数を探します。
これらが正しいシグネチャで定義されていなければ、エラーが発生します。
コード例では、int main(void)
または int main(int argc, char *argv[])
を正しく定義する必要があります。
Windowsアプリケーションの場合
Windowsアプリケーションの場合、通常は WinMain
関数(もしくは wWinMain
)がエントリーポイントとして利用されます。
この関数は標準の main
関数とは異なるシグネチャを持つため、Windowsアプリケーションのプロジェクト設定に合わせて正しいエントリーポイントを定義する必要があります。
DLLビルド時の注意点
DLL をビルドする場合、DllMain
関数を定義するのが一般的です。
ただし、DLL の場合はエントリーポイントの定義は任意であり、必ずしも必要ではありません。
プロジェクトのビルドオプション(たとえば /DLL
オプション)が正しく設定されているか確認することが重要です。
正しいエントリーポイントの定義方法
main関数の正しい定義
コンソールアプリケーションでの標準的なエントリーポイントは main
関数です。
正しい定義方法は、引数の有無に応じて以下のいずれかとなります。
#include <stdio.h>
// 引数無しの main 関数の例
int main(void) {
printf("Hello, world!\n");
return 0;
}
Hello, world!
または、
#include <stdio.h>
// 引数有りの main 関数の例
int main(int argc, char *argv[]) {
printf("Argument count: %d\n", argc);
return 0;
}
Argument count: 1
このように、正しいシグネチャで main
関数を定義することで、リンカーは適切なエントリーポイントを認識できます。
/ENTRYオプションによる指定
特定の環境や要件において、エントリーポイントとして別の関数を指定する場合は、リンカーオプション /ENTRY
を使用できます。
たとえば、以下のサンプルコードでは、独自のエントリーポイント CustomEntry
を定義し、リンカーにその関数を指定します。
#include <stdio.h>
// 独自のエントリーポイント関数
void CustomEntry(void) {
printf("Custom entry point execution.\n");
}
// 通常の main 関数から CustomEntry を呼び出す例
int main(void) {
CustomEntry();
return 0;
}
Custom entry point execution.
この場合、コンパイラやビルド設定で /ENTRY:CustomEntry
オプションを指定することで、リンカーは main
関数ではなく、CustomEntry
関数をエントリーポイントとして認識します。
実例によるエラー解析
ソースコード例の検証
実際のプロジェクトにおいては、ソースコードの各ファイルが正しくリンクされ、エントリーポイントが正確に定義されているかを確認することが大切です。
たとえば、プロジェクト内で main
関数が定義されたファイルがビルド対象に含まれていない場合、LNK1561 エラーが発生します。
以下のリストを参考にソースコードおよびプロジェクト設定を確認してください。
- 各ファイルが正しくビルド対象に設定されているか
main
関数のシグネチャが標準に従っているか- 別のエントリーポイント関数を使用している場合、リンカーオプション
/ENTRY
が正しく設定されているか
エラーメッセージの読み解き方
LNK1561 エラーは以下のようなメッセージとして表示されます。
「エントリ ポイントを定義しなければなりません」
このメッセージは、エントリーポイント関数が見つからなかったことを示しています。
メッセージを受け取った場合は、以下の項目を確認してください。
- 主要なエントリーポイントとなる
main
、wmain
、WinMain
、またはwWinMain
関数がコード内に存在するか - 関数名のタイプミスや大文字・小文字の誤りがないか
- プロジェクト設定やリンクオプションに誤りがないか
これらの確認を行うことで、エラーの原因を特定しやすくなります。
まとめ
この記事では、LNK1561エラーの発生原因とその解決方法について解説しています。
エントリーポイント関数が未定義であること、必要なファイルがリンクされていないこと、関数シグネチャの誤記などが主な原因です。
また、コンソールアプリケーション、Windowsアプリケーション、DLLそれぞれのリンカー動作や正しいエントリーポイントの定義方法、/ENTRYオプションによる指定方法を具体的なサンプルコードを用いて説明しています。
これにより、エラーの理解と対策が明確になり、プロジェクトのビルド時の確認ポイントが把握できます。