リンカ ツール エラー LNK2019

関数 'function' で参照されている extern al のシンボル 'symbol' が未解決です

関数コンパイル済みコードはシンボルへの参照または呼び出しを行いますが、リンカーはライブラリまたはオブジェクト ファイルのいずれにもシンボル定義を見つけることができません。

このエラー メッセージの後に、致命的なエラー LNK1120 が発生します。 エラー LNK1120 を修正するには、最初に LNK2001 エラーと LNK2019 エラーを修正する必要があります。

考えられる原因

このエラーを受け取る方法は多数あります。 これらはすべて、リンカーが解決できなかった、または定義を見つけられなかった関数や変数への参照を含んでいます。 コンパイラは、シンボルが宣言済でない場合は識別できますが、シンボルが定義済でない場合は識別できません。 これは、定義が別のソース ファイルまたはライブラリ内にある可能性があるためです。 シンボルが参照されているが定義されていない場合、リンカーは未解決の extern al シンボル エラーを生成します。

LNK2019 エラーが発生する一般的な問題には次のものがあります。

シンボルの定義を含むソース ファイルがコンパイルされていません

Visual Studio では、シンボルを定義したソース ファイルがプロジェクトの一部としてコンパイルされていることを確認してください。 中間ビルド出力ディレクトリで、一致する .obj ファイルを確認します。 ソース ファイルがコンパイルされていない場合は、ソリューション エクスプローラーでファイルを右クリックし、[プロパティ] を選択してファイルのプロパティをチェックします。 [構成プロパティ]>[General (一般)] ページにアイテムの種類として C/C++ コンパイラが表示されるはずです。 コマンド ラインで、定義を含むソース ファイルがコンパイル済みである必要があります。

シンボルの定義を含むオブジェクト ファイルまたはライブラリがリンクされていない

Visual Studio では、シンボル定義を含むオブジェクトファイルまたはライブラリが、プロジェクトの一部としてリンクされていることを確認してください。 コマンド ラインで、リンクするファイルの一覧にオブジェクト ファイルまたはライブラリがインクルードされることを確認してください。

シンボルの宣言とシンボルの定義でスペルが異なる

宣言と定義の両方、シンボルが使用または呼び出される場所で、正しいスペルと大文字化を使用していることを確認します。

関数が使用されているが、パラメーターの型または数が関数の定義と一致していない

関数の宣言は、定義と一致している必要があります。 関数の呼び出しが宣言と一致することと、宣言が定義と一致することを確認します。 関数テンプレートを呼び出すコードには、定義と同じテンプレート パラメーターを含む一致する関数テンプレート宣言も必要です。 テンプレート宣言の不一致の例については、例セクションのサンプル LNK2019e.cpp を参照してください。

宣言されている関数または変数が定義されていない

LNK2019 は、ヘッダー ファイルに宣言が存在するが、一致する定義が実装されていない場合に発生する可能性があります。 メンバー関数または static データ メンバーの場合、実装にはクラス スコープ セレクターを含める必要があります。 例については、「 Missing Function Body or Variable」を参照してください。

呼び出し規則が関数宣言と関数定義で異なる

一部の呼び出し規則 (__cdecl、、__stdcall__fastcall、および__vectorcall) は、修飾名の一部としてエンコードされます。 呼び出し規則が同じであることを確認します。

シンボルは C ファイルで定義されますが、C++ ファイルでは使用 extern "C" せずに宣言されます

C としてコンパイルされたファイルは、修飾子を使用しない限り、C++ ファイルで宣言された同じシンボルの修飾名とは異なるシンボルの修飾名を extern "C" 作成します。 シンボルごとに宣言がコンパイル リンケージと一致することを確認してください。 同様に、C++ ファイルで定義されているシンボルを C プログラムで使用する場合にも、定義の中で extern "C" を使用します。

static として定義されているシンボルが、後でファイルの外側から参照されている

C++ では、C とは異なり、グローバル定数static リンケージを持ちます。 この制限を回避するには、const の初期化をヘッダー ファイルに記述し、そのヘッダーを .cpp ファイルに含めるか、変数を constant でないものにして constant の参照を使ってアクセスすることもできます。

クラスの static メンバーが定義されていません

static クラス メンバーは一意に定義する必要があります。そうしないと、単一定義規則に違反します。 インラインで定義できない static クラス メンバーは、完全修飾名を使用して 1 つのソース ファイル内で定義する必要があります。 それがまったく定義されていない場合、リンカーは LNK2019 を生成します。

ビルドの依存関係がソリューション内でのプロジェクトの依存関係としてのみ定義されている

前のバージョンの Visual Studio では、このレベルの依存関係で十分でした。 しかし、Visual Studio 2010 以降、Visual Studio ではプロジェクト間参照が必要になりました。 プロジェクトにプロジェクト間参照がない場合は、このリンカー エラーが発生する可能性があります。 この問題を修正するには、プロジェクト間参照を追加します。

エントリ ポイントが定義されていない

アプリケーション コードでは、コンソールアプリケーションの場合は適切なエントリ ポイント main または wmain、Windows アプリケーションの場合は WinMain または wWinMain を定義する必要があります。 詳細については、「main 関数とコマンド ライン引数」または WinMain 関数に関するページを参照してください。 カスタム エントリ ポイントを使用するには、(エントリ ポイント シンボル) リンカー オプションを指定/ENTRYします。

Windows アプリケーション用の設定を使用してコンソール アプリケーションをビルドしている

エラー メッセージが関数function_nameで参照されている未解決externの al シンボルWinMainに似ている場合は、代わりに /SUBSYSTEM:WINDOWS./SUBSYSTEM:CONSOLE この設定の詳細と、Visual Studio でこのプロパティを設定する方法については、(サブシステムの指定) を参照してください。/SUBSYSTEM

コードにリンクされているライブラリとオブジェクト ファイルは、コードと同じアーキテクチャ用にコンパイルする必要があります。 プロジェクトが参照するライブラリが、プロジェクトと同じアーキテクチャ用にコンパイルされている必要があります。 [追加ライブラリ ディレクトリ] /LIBPATH プロパティが、正しいアーキテクチャ用に構築されたライブラリを指していることを確認します。

異なるソース ファイル内でインライン展開されている関数に対して異なるコンパイラ オプションを使用しています

.cpp ファイルで定義されている関数のインライン展開を使用している場合に、異なるソース ファイルで関数のインライン展開のコンパイラ オプションが混在していると、LNK2019 が発生することがあります。 詳細については、「 Function Inlining Problems」を参照してください。

自動変数をそのスコープ外で使用している

自動変数 (関数スコープ) は、その関数のスコープ内でのみ使用できます。 これらの変数を extern として宣言して他のソース ファイルで使用することはできません。 例については、「 Automatic (Function Scope) Variables」を参照してください。

ターゲット アーキテクチャでサポートされていない組み込み関数を呼び出しているか、そのような組み込み関数に引数の型を渡している

例えば、AVX2 の組込み関数を使用しても、/ARCH:AVX2 のコンパイラ オプションを指定しなければ、コンパイラは組込み関数が extern の関数であると判断します。 コンパイラは、インライン命令を生成するのではなく、組み込みと同じ名前で external シンボルへの呼び出しを生成します。 リンカーは、欠落しているこの関数の定義を検索しようとして、LNK2019 を生成します。 ターゲット アーキテクチャでサポートされている組み込み関数と型のみを使用していることを確認してください。

ネイティブの wchar_t を使用するコードとそれを使用しないコードが混在している

Visual Studio 2005 で行われた C++ 言語への準拠作業により、wchar_t は既定でネイティブ型になりました。 すべてのファイルが同じ /Zc:wchar_t 設定を使用してコンパイルされていない場合、型参照が互換性のある型に解決されない可能性があります。 すべてのライブラリ ファイルとオブジェクト ファイルの wchar_t 型に互換性があることを確認してください。 wchar_t の型定義から更新するか、コンパイル時に一貫した /Zc:wchar_t の設定を使用します。

static Visual Studio 2015 より前のバージョンの Visual Studio を使用してビルドされたライブラリでは、UCRT にリンクするとLNK2019 エラーが発生する可能性があります。 UCRT ヘッダー ファイル<stdio.h><conio.h>および<wchar.h>関数としてinline多くの*printf*バリエーション*scanf*を定義します。 インライン関数は、より小さな一連の共通関数によって実装されます。 インライン関数の個々のエクスポートは、一般的な関数のみをエクスポートする標準 UCRT ライブラリでは使用できません。 この問題を解決するには、いくつかの方法があります。 推奨される方法は、現在のバージョンの Visual Studio でレガシ ライブラリを再構築することです。 ライブラリ コードで、エラーの原因となった関数の*scanf*定義*printf*に標準ヘッダーが使用されていることを確認します。 リビルドできないレガシ ライブラリのもう 1 つのオプションは、リンクするライブラリの一覧に追加 legacy_stdio_definitions.lib することです。 このライブラリ ファイルは、UCRT ヘッダーに *printf* インライン化される関数と *scanf* シンボルを提供します。 詳細については、「アップグレードに関する潜在的な問題の概要」の「ライブラリ」セクションを参照してください。

サードパーティ ライブラリの問題と vcpkg

ビルドの一部としてサード パーティ製ライブラリを構成しようとしたときにこのエラーが表示される場合は、vcpkg の使用を検討してください。 vcpkg は、既存の Visual Studio ツールを使用してライブラリをインストールおよびビルドする C++ パッケージ マネージャーです。 vcpkg は、拡大し続ける サードパーティ 製ライブラリの一覧をサポートしています。 プロジェクトの一部として、ビルドの成功に必要なすべての構成プロパティと依存関係が設定されます。

診断ツール

リンカーが特定のシンボル定義を見つけられない理由を説明するのが難しい場合があります。 多くの場合、その定義を含むコードをビルドに含めていないことが問題となります。 または、ビルド オプションによって、external シンボルに対して異なる装飾名が作成されています。 LNK2019 エラーを診断するために役立ついくつかのツールとオプションを紹介します。

  • /VERBOSE リンカー オプションを使用すると、リンカーがどのファイルを参照しているかを確認できます。 このオプションは、シンボルの定義の入ったファイルがビルドに含まれているかどうかを確認するために役立ちます。

  • DUMPBIN ユーティリティーの /EXPORTS/SYMBOLS オプションを使用すると、.dll やオブジェクトまたはライブラリ ファイルで定義されているシンボルを確認できます。 エクスポートされた装飾名が、リンカーで検索する装飾名と一致することを確認してください。

  • UNDNAME ユーティリティを使用すると、装飾名に対応する、装飾されていない external シンボルを表示できます。

LNK2019 エラーの原因となるコードの例と、エラーの修正方法に関する情報を次に示します。

シンボルが宣言されているが、定義されていない

この例では、external の変数が宣言されていますが、定義されていません:

// LNK2019.cpp
// Compile by using: cl /EHsc /W4 LNK2019.cpp
// LNK2019 expected
extern char B[100];   // B isn't available to the linker
int main() {
   B[0] = ' ';   // LNK2019
}

変数と関数が宣言されている extern が、定義が指定されていない別の例を次に示します。

// LNK2019c.cpp
// Compile by using: cl /EHsc LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
   i++;
   g();
}
int main() {}

ig がビルドに含まれるいずれかのファイルで定義されていなければ、リンカーは LNK2019 を生成します。 このエラーを修正するには、定義を含むソース コード ファイルをコンパイルの一部に組み込みます。 または、定義を含むファイルを.libリンカーに渡.objすことができます。

static データ メンバーが宣言されているが、定義されていない

LNK2019 は、static データ メンバーが宣言されているものの定義がなされていない場合に発生することもあります。 次の例は LNK2019 を生成します。その修正方法も示しています。

// LNK2019b.cpp
// Compile by using: cl /EHsc LNK2019b.cpp
// LNK2019 expected
struct C {
   static int s;
};

// Uncomment the following line to fix the error.
// int C::s;

int main() {
   C c;
   C::s = 1;
}

宣言パラメーターが定義と一致しません

関数テンプレートを呼び出すコードには、一致する関数テンプレート宣言が必要です。 宣言には、定義と同じテンプレート パラメーターを含める必要があります。 次の例では、ユーザー定義の演算子で LNK2019 が発生します。その修正方法も示しています。

// LNK2019e.cpp
// compile by using: cl /EHsc LNK2019e.cpp
// LNK2019 expected
#include <iostream>
using namespace std;

template<class T> class
Test {
   // The operator<< declaration doesn't match the definition below:
   friend ostream& operator<<(ostream&, Test&);
   // To fix, replace the line above with the following:
   // template<typename T> friend ostream& operator<<(ostream&, Test<T>&);
};

template<typename T>
ostream& operator<<(ostream& os, Test<T>& tt) {
   return os;
}

int main() {
   Test<int> t;
   cout << "Test: " << t << endl;   // LNK2019 unresolved external
}

一貫性のない wchar_t 型の定義

このサンプルでは、WCHAR を使用する export を持つ DLL を作成し、wchar_t に解決しています。

// LNK2019g.cpp
// compile with: cl /EHsc /LD LNK2019g.cpp
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}

次のサンプルでは、前のサンプルの DLL を使用し、unsigned short*WCHAR* の型が同じではないため、LNK2019 が生成されます。

// LNK2019h.cpp
// compile by using: cl /EHsc LNK2019h LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);

int main() {
   func(0);
}

このエラーを修正するには、次を使用/Zc:wchar_t-して LNK2019g.cpp にwchar_t変更unsigned shortまたはWCHARコンパイルします。

関連項目

LNK2019、LNK2001、およびLNK1120エラーの考えられる原因と解決策の詳細については、Stack Overflow の質問 What is an undefined reference/unresolved external symbol error and how do I fix it?を参照してください。