リンカ ツール エラー LNK2019
更新 : 2007 年 11 月
エラー メッセージ
未解決の外部シンボル 'symbol' が関数 'function' で参照されました。
function に未定義の外部シンボル (symbol) が見つかりました。このエラーを解決するには、シンボルを定義するか、シンボルを参照するコードを削除します。詳細については、次のトピックを参照してください。
次のサンプルは LNK2019 を生成します。
// LNK2019.cpp
// LNK2019 expected
extern char B[100]; // B is not in avilable to the linker
int main() {
B[0] = ' ';
}
LNK2019 は、宣言した静的データ メンバを定義しなかった場合にも発生します。次のサンプルは LNK2019 を生成します。
// LNK2019b.cpp
// LNK2019 expected
struct C {
static int s;
};
// Uncomment the following line to resolve.
// int C::s;
int main() {
C c;
C::s = 1;
}
次のサンプルを例に取ります。
// LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
i++;
g();
}
int main() {}
ビルドに取り込むファイルのうちの 1 つで i と g が定義されていないと、LNK2019 が生成されます。この定義は、コンパイルの一部として定義を含むソース コード ファイルをインクルードすることで追加できます。または、定義を含む .obj ファイルまたは .lib ファイルをリンカに渡します。
以前のリリースで作成され、現在のバージョンにアップグレードされた C++ プロジェクトについて、__UNICODE が定義され、エントリ ポイントが WinMain であった場合は、エントリ ポイント関数の名前を _tWinMain または wWinMain に変更する必要があります。
LNK2019 エラーの一般的な原因は、次のとおりです。
シンボルの宣言にスペル ミスがあるため、シンボルの定義での名前と異なっています。
関数が使用されていますが、パラメータの型または数が関数定義と一致しません。
呼び出し規約 (__cdecl、__stdcall、または __fastcall) が、関数宣言と関数定義で異なっています。
シンボル定義が C プログラムとしてコンパイルされたファイルにあり、シンボルは C++ ファイル内で extern "C" 修飾子なしで宣言されています。その場合は、宣言を変更します。たとえば、次のコードがあるとします。
extern int i; extern void g();
代わりに、次のコードを使用します。
extern "C" int i; extern "C" void g();
同様に、C プログラムで使用するシンボルを C++ ファイル内で定義する場合は、extern "C" を使用して定義します。
シンボルが静的として定義されてから、ファイルの外側で参照されています。C++ のグローバル定数は、static リンケージを持つ点が C と異なります。この対策としては、const の初期化をヘッダー ファイルにインクルードし、そのヘッダー ファイルを .cpp ファイルに取り込みます。別の対策としては、変数を定数以外にし、アクセスするときに定数参照を使用します。
クラスの静的メンバが定義されていません。たとえば、クラス宣言のメンバ変数 si を別個に定義する必要があります。
// LNK2019d.cpp #include <stdio.h> struct X { static int si; }; // int X::si = 0; // uncomment this line to resolve int main() { X *px = new X[2]; printf_s("\n%d",px[0].si); // LNK2019 }
次のサンプルは、ユーザー定義の演算子に関する LNK2019 を生成します。
// LNK2019e.cpp
// compile with: /EHsc
// LNK2019 expected
#include <iostream>
using namespace std;
template<class T> class
Test {
friend ostream& operator<<(ostream&, Test&);
// Uncomment the following line to resolve.
// 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; // unresolved external
}
/VERBOSE リンカ オプションを使用すると、リンカが参照しているファイルを確認できます。また、DUMPBIN ユーティリティの /EXPORTS オプションおよび /SYMBOLS オプションを使用すると、dll ファイル、オブジェクト ファイル、ライブラリ ファイルに定義されているシンボルを確認できます。
LNK2019 の詳細については、マイクロソフト サポート技術情報 https://support.microsoft.com を参照してください。
LNK2019 は、"Visual Studio .NET 2003 : テンプレートのフレンドおよび特化された形式" に対して行った準拠作業の結果として生成されることもあります。Visual Studio .NET 2003 では、関数テンプレートと同じ名前を持つフレンド関数の宣言は、テンプレート引数がフレンド宣言に明示的に指定されていない限り、関数テンプレートを参照しません。
テンプレート引数を指定しないと、フレンド宣言は非テンプレート関数を宣言します。
詳細については、「Summary of Compile-Time Breaking Changes」を参照してください。
Visual Studio .NET 2003 と Visual Studio .NET の両方のバージョンの Visual C++ で有効なコードを作成するには、フレンド関数のテンプレート引数リストを明示的に指定します。
// LNK2019f.cpp
// LNK2019 expected
template<class T>
void f(T) {}
template<class T>
struct S {
friend void f(T);
// try the folowing line instead
// friend void f<T>(T);
};
int main() {
S<int> s;
f(1); // unresolved external
}
LNK2019 は、/Zc:wchar_t が既定でオンになった Visual C++ 2005 で行った準拠作業の結果として発生することもあります。すべてのモジュールが同じ設定の /Zc:wchar_t でコンパイルされていない場合は、型参照が互換性のある型に解決されません。この問題を解決するには、/Zc:wchar_t を適切に設定してコンパイルする (たとえば、旧バージョンのモジュールにリンクされる Visual C++ 2005 ツールセットを使用してモジュールをビルドするときに /Zc:wchar_t- を使用する) か、または可能であれば型を互換性のある型に更新するかして、モジュール内のすべての型が確実に互換性を持つようにします。
/Zc:wchar_t は既定でオンになったため、コメント プラグマまたはコマンド ラインからの comsupp.lib への明示的な参照は、comsuppw.lib または comsuppwd.lib のどちらかを使うように変更する必要があります。ただし、/Zc:wchar_t- を指定してコンパイルするときは、これまで同様に comsupp.lib を使用する必要があります。
詳細については、「Visual C++ 2005 コンパイラの互換性に影響する変更点」および「/Zc:wchar_t (wchar_t をネイティブ型として認識)」を参照してください。
次のサンプルは、WCHAR を使用するエクスポートを作成します。これは wchar_t に解決されます。
// LNK2019g.cpp
// compile with: /LD
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}
次のサンプルは LNK2019 を生成します。
// LNK2019h.cpp
// compile with: LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);
int main() {
func(0);
}
このエラーを解決するには、unsigned short を wchar_t または WCHAR に変更するか、/Zc:wchar_t- を指定して LNK2019g.cpp をコンパイルします。
/SUBSYSTEM:WINDOWS を使用してコンソール アプリケーションをビルドしている場合に LNK2019 が発生することもあります。未解決のシンボルは _WinMain@16 になります。この場合は、単に /SUBSYSTEM:CONSOLE とリンクします。