リンカー

C言語 LNK1561エラーについて解説

c言語で発生するLNK1561は、リンカーが実行開始時に呼び出すエントリーポイント、通常はmain関数を検出できない場合に起こるエラーです。

ソースコード内にmain関数が正しく記述されているか確認する必要があります。

エントリーポイントの定義や関数シグネチャに誤りが無いかチェックすることで、エラー解消に繋がります。

エラー発生の原因

エントリーポイント関数の未定義

エントリーポイント関数が定義されていない場合、リンカーは起動時に呼び出すべき関数を見つけられず、エラー LNK1561 を発生させます。

C言語の場合、通常は main関数がエントリーポイントとして認識されますが、コード内に main関数が存在しないとこのエラーが発生します。

たとえば、下記のコードはエントリーポイントが存在しないため、リンクエラーが発生します。

#include <stdio.h>
// グローバル変数の定義のみで、main 関数が定義されていない例
int globalVariable = 0;
LNK1561: エントリーポイントを定義しなければなりません

ファイルリンクの不備

エントリーポイント関数が実装されているソースファイルがビルドに含まれていない場合も、同様にリンカーはエントリーポイントを見つけられずエラーとなります。

たとえば、複数ソースファイルからビルドを行う場合、main関数が実装されたファイルがリンクリストに含まれているかどうかを確認する必要があります。

リンク設定やプロジェクト構成のミスにより、意図したファイルが除外されるケースがあります。

関数シグネチャの誤記

エントリーポイントである main関数のシグネチャ(返り値や引数の型、数)が誤って定義されている場合も、リンカーが正しいエントリーポイントとして認識できなくなります。

たとえば、Main と大文字で記述したり、引数の型や順序を間違えたりすると、リンカーはこれをエントリーポイント関数と見なさないため、エラーが発生します。

正しいシグネチャは次のいずれかとなります。

  • コンソールアプリケーションの場合:

int main(int argc, char *argv[]) または int main(void)

リンカーの動作とエントリーポイントの役割

リンカーツールの基本動作

リンカーは、ビルドされたオブジェクトファイルやライブラリを結合し、最終的な実行形式を生成します。

その際、各アプリケーションにおいて最初に実行されるべき関数(エントリーポイント)を探し出します。

通常、リンカーは以下の名前の関数を順に検索します。

  • コンソールアプリケーション: 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 エラーは以下のようなメッセージとして表示されます。

「エントリ ポイントを定義しなければなりません」

このメッセージは、エントリーポイント関数が見つからなかったことを示しています。

メッセージを受け取った場合は、以下の項目を確認してください。

  • 主要なエントリーポイントとなる mainwmainWinMain、または wWinMain 関数がコード内に存在するか
  • 関数名のタイプミスや大文字・小文字の誤りがないか
  • プロジェクト設定やリンクオプションに誤りがないか

これらの確認を行うことで、エラーの原因を特定しやすくなります。

まとめ

この記事では、LNK1561エラーの発生原因とその解決方法について解説しています。

エントリーポイント関数が未定義であること、必要なファイルがリンクされていないこと、関数シグネチャの誤記などが主な原因です。

また、コンソールアプリケーション、Windowsアプリケーション、DLLそれぞれのリンカー動作や正しいエントリーポイントの定義方法、/ENTRYオプションによる指定方法を具体的なサンプルコードを用いて説明しています。

これにより、エラーの理解と対策が明確になり、プロジェクトのビルド時の確認ポイントが把握できます。

関連記事

Back to top button
目次へ