リンカ ツール エラー 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 とリンクします。