Linkertoolfehler LNK2019

Aktualisiert: November 2007

Fehlermeldung

Verweis auf nicht aufgelöstes externes Symbol 'Symbol' in Funktion 'Funktion'
unresolved external symbol 'symbol' referenced in function 'function'

In function wurde ein nicht definiertes externes Symbol (symbol) gefunden. Um diesen Fehler zu beheben, geben Sie eine Definition für das Symbol an oder entfernen den Code, der darauf verweist. Weitere Informationen finden Sie unter

Im folgenden Beispiel wird der Fehler LNK2019 generiert:

// LNK2019.cpp
// LNK2019 expected
extern char B[100];   // B is not in avilable to the linker
int main() {
   B[0] = ' ';
}

LNK2019 kann auch auftreten, wenn Sie einen statischen Datenmember deklarieren, jedoch nicht definieren. Im folgenden Beispiel wird der Fehler LNK2019 generiert:

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

Betrachten Sie das folgende Beispiel:

// LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
   i++;
   g();
}
int main() {}

Wenn i und g nicht in einer der Builddateien definiert sind, generiert der Linker den Fehler LNK2019. Diese Definitionen können hinzugefügt werden, indem Sie die Quellcodedatei einlesen, die die Definitionen als Teil der Kompilierung enthält. Alternativ können Sie OBJ- oder LIB-Dateien übergeben, die die Definitionen für den Linker enthalten.

Wenn bei C++-Projekten aus früheren Versionen, die auf die aktuelle Version aktualisiert wurden, __UNICODE definiert wurde und der Einstiegspunkt WinMain war, müssen Sie den Namen der Einstiegspunktfunktion entweder in _tWinMain oder in wWinMain ändern.

Im Folgenden sind einige häufige Ursachen für LNK2019 beschrieben:

  • Die Symboldeklaration enthält einen Rechtschreibfehler, sodass die Namen von Symboldefinition und -deklaration nicht übereinstimmen.

  • Eine Funktion wurde zwar verwendet, der Typ oder die Anzahl ihrer Parameter stimmen jedoch nicht mit der Funktionsdefinition überein.

  • Die Aufrufkonvention (__cdecl__stdcall oder __fastcall) weist Unterschiede zur Verwendung der Funktionsdeklaration und -definition auf.

  • Die Symboldefinitionen sind in einer Datei enthalten, die als C-Programm kompiliert wurde, die Symbole wurden jedoch in einer C++-Datei ohne extern "C"-Modifizierer deklariert. In diesem Fall ändern Sie die Deklaration. Verwenden Sie anstelle von

    extern int i;
    extern void g();
    

    folgenden Code:

    extern "C" int i;
    extern "C" void g();
    

    Auch wenn ein Symbol in einer C++-Datei definiert wird, die von einem C-Programm verwendet wird, geben Sie extern "C" in der Definition an.

  • Ein Symbol wird als static definiert, später wird jedoch außerhalb der Datei darauf verwiesen. In C++ haben globale Konstanten anders als in C eine static-Verknüpfung. Um diese Einschränkung zu umgehen, können Sie die const-Initialisierungen in eine Headerdatei einfügen und diesen Header anschließend in die CPP-Dateien einlesen, oder Sie deklarieren die Variable als nicht konstant und verwenden einen konstanten Verweis, um darauf zuzugreifen.

  • Ein statischer Member einer Klasse wurde nicht definiert. Die Membervariable si in der unten aufgeführten Klassendeklaration sollte beispielsweise separat definiert werden:

    // 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
    }
    

Im folgenden Beispiel wird der Fehler LNK2019 bei einem benutzerdefinierten Operator generiert.

// 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
}

Mithilfe der /VERBOSE-Linkeroption können Sie feststellen, auf welche Dateien vom Linker verwiesen wird. Mit den Optionen /EXPORTS und /SYMBOLS des DUMPBIN-Dienstprogramms können Sie auch herausfinden, welche Symbole in der DLL und in den Objekt-/Bibliotheksdateien definiert sind.

Weitere Informationen zu LNK2019 finden Sie in der Microsoft Knowledge Base unter https://support.microsoft.com/?in=de.

LNK2019 kann auch aufgrund einer Konformitätsverbesserung in Visual Studio .NET 2003 ausgegeben werden: Vorlagen von friends und Spezialisierungen. In Visual Studio .NET 2003 bezieht sich die Deklaration einer Friend-Funktion mit demselben Namen wie die Funktionsvorlage nicht auf diese Funktionsvorlage, wenn in der Friend-Deklaration nicht explizit Vorlagenargumente angegeben sind.

Wenn Sie keine Vorlagenargumente angeben, deklariert die Friend-Deklaration eine nicht auf Vorlagen basierende Funktion.

Weitere Informationen finden Sie unter Übersicht über die wichtigsten Änderungen bei der Kompilierzeit.

In Code, der sowohl in der Visual Studio .NET 2003-Version als auch in der Visual Studio .NET-Version von Visual C++ gültig ist, geben Sie explizit die Vorlagenargumentliste der friend-Funktion an.

// 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 kann außerdem infolge einer Konformitätsverbesserung von Visual C++ 2005 ausgegeben werden, durch die /Zc:wchar_t nun standardmäßig aktiviert ist. Es wurden möglicherweise nicht alle Module mit denselben /Zc:wchar_t-Einstellungen kompiliert, sodass Typenverweise nicht in kompatible Typen aufgelöst werden können. Um dies zu beheben, müssen die Typen in allen Modulen kompatibel sein, indem sie entweder mit den entsprechenden /Zc:wchar_t-Einstellungen kompiliert werden (z. B. durch Verwendung von /Zc:wchar_t- beim Erstellen von Modulen mit dem Visual C++ 2005-Toolset, die mit Modulen älterer Versionen verknüpft werden) oder indem Sie, wenn möglich, die Typen so aktualisieren, dass sie kompatibel sind.

Explizite Verweise auf comsupp.lib, sei es aus dem comment-Pragma oder über die Befehlszeile, sollten so geändert werden, dass entweder comsuppw.lib oder comsuppwd.lib verwendet wird, da /Zc:wchar_t nun standardmäßig aktiviert ist. Beim Kompilieren mit /Zc:wchar_t- sollte auch weiterhin comsupp.lib verwendet werden.

Weitere Informationen finden Sie unter Wichtige Änderungen im Visual C++ 2005-Compiler und /Zc:wchar_t (wchar_t ist der systemeigene Typ).

Im folgenden Beispiel wird eine Exportdatei erstellt, die WCHAR verwendet, das in wchar_t aufgelöst wird.

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

Im folgenden Beispiel wird der Fehler LNK2019 generiert:

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

int main() {
   func(0);
}

Um diesen Fehler zu beheben, ändern Sie entweder unsigned short zu wchar_t oder zu WCHAR, oder Sie kompilieren LNK2019g.cpp mit /Zc:wchar_t-.

LNK2019 kann auch auftreten, wenn Sie eine Konsolenanwendung mit /SUBSYSTEM:WINDOWS erstellen. Das nicht aufgelöste Symbol ist _WinMain@16. In diesem Fall erstellen Sie einfach eine Verknüpfung mit /SUBSYSTEM:CONSOLE.