Linkertoolfehler LNK2005

Symbol, das bereits im -Objekt definiert ist

Das Symbolsymbol wurde mehr als einmal definiert.

Auf diesen Fehler folgt der schwerwiegende Fehler LNK1169.

Mögliche Ursachen und Lösungen

Im Allgemeinen bedeutet dieser Fehler, dass Sie die Eine-Definition-Regel verletzt haben, die nur eine Definition für alle verwendeten Vorlagen, Funktionen, Typen oder Objekte in einer bestimmten Objektdatei und nur eine Definition in der gesamten ausführbaren Datei für extern sichtbare Objekte oder Funktionen zulässt.

Hier sind einige häufige Ursachen für diesen Fehler.

  • Dieser Fehler kann auftreten, wenn eine Headerdatei eine Variable definiert. Wenn Sie diese Headerdatei z. B. in mehr als eine Quelldatei in Ihr Projekt einlesen, tritt ein Fehler auf:

    // LNK2005_global.h
    int global_int;  // LNK2005
    

    Folgende Lösungen sind möglich:

    • Deklarieren Sie die extern Variable in der Headerdatei: extern int global_int;, definieren Sie sie, und initialisieren Sie sie optional in nur einer Quelldatei: int global_int = 17;. Diese Variable ist jetzt eine globale Variable, die Sie in jeder externQuelldatei verwenden können, indem Sie sie deklarieren, z. B. durch Hinzufügen der Headerdatei. Wir empfehlen diese Lösung für Variablen, die global sein müssen, aber eine gute Softwareentwicklungsübung minimiert globale Variablen.

    • Deklarieren Sie die Variable static: static int static_int = 17;. Dadurch wird der Bereich der Definition auf die aktuelle Objektdatei beschränkt, und mehrere Objektdateien können über eine eigene Kopie der Variablen verfügen. Es wird nicht empfohlen, statische Variablen in Headerdateien zu definieren, da dies zu Verwechslungen mit globalen Variablen führen kann. Verschieben Sie statische Variablendefinitionen lieber in die Quelldateien, die sie verwenden.

    • Deklarieren Sie die Variablenauswahl: __declspec(selectany) int global_int = 17;. Dies weist den Linker an, eine Definition für die Verwendung durch alle externen Verweise zu wählen und den Rest zu verwerfen. Diese Lösung ist manchmal nützlich, wenn Importbibliotheken kombiniert werden. Andernfalls wird dies nicht empfohlen, um Linkerfehler zu vermeiden.

  • Dieser Fehler kann auftreten, wenn eine Headerdatei eine Funktion definiert, die nicht ist inline. Wenn Sie diese Headerdatei in mehr als eine Quelldatei hinzufügen, erhalten Sie mehrere Definitionen der Funktion in der ausführbaren Datei.

    // LNK2005_func.h
    int sample_function(int k) { return 42 * (k % 167); }  // LNK2005
    

    Folgende Lösungen sind möglich:

    • Fügen Sie der inline Funktion das Schlüsselwort hinzu:

      // LNK2005_func_inline.h
      inline int sample_function(int k) { return 42 * (k % 167); }
      
    • Entfernen Sie den Funktionstext aus der Headerdatei, lassen Sie nur die Deklaration, und implementieren Sie dann die Funktion in einer einzigen Quelldatei:

      // LNK2005_func_decl.h
      int sample_function(int);
      
      // LNK2005_func_impl.cpp
      int sample_function(int k) { return 42 * (k % 167); }
      
  • Dieser Fehler kann auch auftreten, wenn Sie Memberfunktionen außerhalb der Klassendeklaration in einer Headerdatei definieren:

    // LNK2005_member_outside.h
    class Sample {
    public:
        int sample_function(int);
    };
    int Sample::sample_function(int k) { return 42 * (k % 167); }  // LNK2005
    

    Um dieses Problem zu beheben, verschieben Sie die Memberfunktionsdefinitionen innerhalb der -Klasse. Memberfunktionen, die in einer Klassendeklaration definiert sind, sind implizit inline.

    // LNK2005_member_inline.h
    class Sample {
    public:
        int sample_function(int k) { return 42 * (k % 167); }
    };
    
  • Dieser Fehler kann auftreten, wenn Sie mehrere Versionen der Standardbibliothek oder CRT verknüpfen. Wenn Sie beispielsweise versuchen, sowohl die CRT-Bibliotheken für einzelhandel als auch debuggen, die statischen und dynamischen Versionen einer Bibliothek oder zwei verschiedene Versionen einer Standardbibliothek mit Ihrer ausführbaren Datei zu verknüpfen, wird dieser Fehler möglicherweise mehrmals gemeldet. Um dieses Problem zu beheben, entfernen Sie alle Bis auf eine Kopie jeder Bibliothek aus dem Linkbefehl. Es wird nicht empfohlen, Einzelhandels- und Debugbibliotheken oder verschiedene Versionen einer Bibliothek in derselben ausführbaren Datei zu mischen.

    Damit der Linker andere Bibliotheken als die Standardbibliotheken verwenden soll, geben Sie in der Befehlszeile die zu verwendenden Bibliotheken an, und verwenden Sie die Option /NODEFAULTLIB , um die Standardbibliotheken zu deaktivieren. Fügen Sie in der IDE Verweise auf Ihr Projekt hinzu, um die zu verwendenden Bibliotheken anzugeben, und öffnen Sie dann das Dialogfeld Eigenschaftenseiten für Ihr Projekt. Legen Sie auf der Eigenschaftenseite Linker, Eingabe entweder Alle Standardbibliotheken ignorieren oder Bestimmte Standardbibliotheken ignorieren fest, um die Standardbibliotheken zu deaktivieren.

  • Dieser Fehler kann auftreten, wenn Sie die Verwendung statischer und dynamischer Bibliotheken kombinieren, wenn Sie die Option /clr verwenden. Dieser Fehler kann beispielsweise auftreten, wenn Sie eine DLL für die Verwendung in Der ausführbaren Datei erstellen, die in der statischen CRT verknüpft ist. Um dieses Problem zu beheben, verwenden Sie nur statische Bibliotheken oder nur dynamische Bibliotheken für die gesamte ausführbare Datei und für alle Bibliotheken, die Sie erstellen, um sie in der ausführbaren Datei zu verwenden.

  • Dieser Fehler kann auftreten, wenn es sich bei dem Symbol um eine gepackte Funktion handelt (die durch Kompilieren mit /Gy erstellt wurde) und es in mehr als einer Datei enthalten war, aber zwischen Kompilierungen geändert wurde. Kompilieren Sie alle Dateien, die die gepackte Funktion enthalten, erneut, um dieses Problem zu beheben.

  • Dieser Fehler kann auftreten, wenn das Symbol in zwei Memberobjekten in verschiedenen Bibliotheken unterschiedlich definiert ist und beide Memberobjekte verwendet werden. Eine Möglichkeit, dieses Problem zu beheben, wenn die Bibliotheken statisch verknüpft sind, besteht in der Verwendung des Memberobjekts aus nur einer Bibliothek und dem ersten Hinzufügen dieser Bibliothek in die Linkerbefehlszeile. Um beide Symbole zu verwenden, müssen Sie eine Möglichkeit zur Unterscheidung erstellen. Wenn Sie beispielsweise die Bibliotheken aus der Quelle erstellen können, können Sie jede Bibliothek in einem eindeutigen Namespace umschließen. Alternativ können Sie eine neue Wrapperbibliothek erstellen, die eindeutige Namen verwendet, um Verweise auf eine der ursprünglichen Bibliotheken zu umschließen, die neue Bibliothek mit der ursprünglichen Bibliothek zu verknüpfen und die ausführbare Datei dann mit Ihrer neuen Bibliothek anstelle der ursprünglichen Bibliothek zu verknüpfen.

  • Dieser Fehler kann auftreten, wenn eine extern const Variable zweimal definiert ist und in jeder Definition über einen anderen Wert verfügt. Um dieses Problem zu beheben, definieren Sie die Konstante nur einmal, oder verwenden Sie Namespaces enum class oder Definitionen, um die Konstanten zu unterscheiden.

  • Dieser Fehler kann auftreten, wenn Sie uuid.lib in Kombination mit anderen LIB-Dateien verwenden, die GUIDs definieren (z. B. oledb.lib und adsiid.lib). Beispiel:

    oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject
    already defined in uuid.lib(go7.obj)
    

    Um dieses Problem zu beheben, fügen Sie /FORCE:MULTIPLE den Linkerbefehlszeilenoptionen hinzu, und stellen Sie sicher, dass uuid.lib die erste Bibliothek ist, auf die verwiesen wird.