リンカ ツール エラー LNK2019

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

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

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

考えられる原因

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

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

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

Visual Studio では、シンボルを定義したソース ファイルがプロジェクトの一部としてコンパイルされていることを確認してください。 中間ビルド出力ディレクトリで、一致する .obj ファイルを確認します。 ソース ファイルがコンパイルされていない場合は、ソリューション エクスプローラー 内のファイルを右クリックし、Properties を選択してファイルのプロパティを確認します。 [構成プロパティ]>[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 アプリケーション用の設定を使用してコンソール アプリケーションをビルドしている

エラー メッセージが 関数で参照されている未解決の external シンボル WinMainfunction_name のような場合は、/SUBSYSTEM:WINDOWS の代わりに /SUBSYSTEM:CONSOLE を使用してリンクします。 この設定の詳細と、Visual Studio でこのプロパティを設定する手順の詳細については、「 /SUBSYSTEM (Specify 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 の設定を使用します。

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

サードパーティ製のライブラリをビルドの一部として設定しようとした際にこのエラーが表示された場合は、C++ パッケージ マネージャである vcpkg を使用してライブラリをインストールし、ビルドすることを検討してください。 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 を生成します。 このエラーを修正するには、定義を含むソース コード ファイルをコンパイルの一部に組み込みます。 また、定義を含んだ .obj ファイルや .lib ファイルをリンカーに渡すこともできます。

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);
}

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

その他のリソース

LNK2001 に関する考えられる原因と解決策の詳細は、Stack Overflow の質問の「未定義の参照または未解決の extern シンボル エラーの意味と解決方法」を参照してください。