Errore degli strumenti del linker LNK2005

simbolo già definito nell'oggetto

Il simbolo del simbolo è stato definito più di una volta.

Questo errore è seguito da un errore irreversibile LNK1169.

Possibili cause e soluzioni

In genere, questo errore indica che è stata interrotta una regola di definizione, che consente una sola definizione per qualsiasi modello, funzione, tipo o oggetto usato in un determinato file oggetto e una sola definizione nell'intero eseguibile per oggetti o funzioni visibili esternamente.

Ecco alcune cause comuni per questo errore.

  • Questo errore può verificarsi quando un file di intestazione definisce una variabile. Ad esempio, se si include questo file di intestazione in più file di origine nel progetto, viene restituito un errore:

    // LNK2005_global.h
    int global_int;  // LNK2005
    

    Tra le possibili soluzioni vi sono le seguenti:

    • Dichiarare la variabile nel file di intestazione extern : extern int global_int;, quindi definirla e, facoltativamente, inizializzarla in un unico file di origine: int global_int = 17;. Questa variabile è ora un elemento globale che è possibile usare in qualsiasi file di origine dichiarandolo extern, ad esempio includendo il file di intestazione. È consigliabile usare questa soluzione per le variabili che devono essere globali, ma una buona procedura di progettazione del software riduce al minimo le variabili globali.

    • Dichiarare la variabile statica: static int static_int = 17;. Ciò limita l'ambito della definizione al file oggetto corrente e consente a più file oggetto di avere la propria copia della variabile. Non è consigliabile definire variabili statiche nei file di intestazione a causa della potenziale confusione con le variabili globali. Preferisce spostare le definizioni di variabili statiche nei file di origine che le usano.

    • Dichiarare la variabile selectany: __declspec(selectany) int global_int = 17;. Questo indica al linker di selezionare una definizione da usare da tutti i riferimenti esterni e di eliminare il resto. Questa soluzione è talvolta utile quando si combinano librerie di importazione. In caso contrario, non è consigliabile per evitare errori del linker.

  • Questo errore può verificarsi quando un file di intestazione definisce una funzione che non inlineè . Se si include questo file di intestazione in più file di origine, si ottengono più definizioni della funzione nel file eseguibile.

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

    Tra le possibili soluzioni vi sono le seguenti:

    • Aggiungere la inline parola chiave alla funzione :

      // LNK2005_func_inline.h
      inline int sample_function(int k) { return 42 * (k % 167); }
      
    • Rimuovere il corpo della funzione dal file di intestazione e lasciare solo la dichiarazione, quindi implementare la funzione in un solo file di origine:

      // LNK2005_func_decl.h
      int sample_function(int);
      
      // LNK2005_func_impl.cpp
      int sample_function(int k) { return 42 * (k % 167); }
      
  • Questo errore può verificarsi anche se si definiscono funzioni membro esterne alla dichiarazione di classe in un file di intestazione:

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

    Per risolvere questo problema, spostare le definizioni di funzione membro all'interno della classe . Le funzioni membro definite all'interno di una dichiarazione di classe vengono inlined in modo implicito.

    // LNK2005_member_inline.h
    class Sample {
    public:
        int sample_function(int k) { return 42 * (k % 167); }
    };
    
  • Questo errore può verificarsi se si collega più di una versione della libreria standard o CRT. Ad esempio, se si tenta di collegare entrambe le librerie CRT al dettaglio e di debug o sia le versioni statiche che dinamiche di una libreria o due versioni diverse di una libreria standard al file eseguibile, questo errore può essere segnalato molte volte. Per risolvere questo problema, rimuovere tutte le librerie, ma una copia di ogni libreria dal comando di collegamento. Non è consigliabile combinare librerie di vendita al dettaglio e di debug o versioni diverse di una libreria nello stesso eseguibile.

    Per indicare al linker di usare librerie diverse dalle impostazioni predefinite, nella riga di comando specificare le librerie da usare e usare l'opzione /NODEFAULTLIB per disabilitare le librerie predefinite. Nell'IDE aggiungere riferimenti al progetto per specificare le librerie da usare e quindi aprire la finestra di dialogo Pagine delle proprietà per il progetto e nella pagina delle proprietà Linker, Input impostare Ignora tutte le librerie predefinite o Ignora librerie predefinite specifiche per disabilitare le librerie predefinite.

  • Questo errore può verificarsi se si combina l'uso di librerie statiche e dinamiche quando si usa l'opzione /clr . Ad esempio, questo errore può verificarsi se si compila una DLL da usare nel file eseguibile che collega in CRT statico. Per risolvere questo problema, usare solo librerie statiche o solo librerie dinamiche per l'intero eseguibile e per tutte le librerie compilate da usare nel file eseguibile.

  • Questo errore può verificarsi se il simbolo è una funzione in pacchetto (creata tramite la compilazione con /Gy) ed è stata inclusa in più file, ma è stata modificata tra le compilazioni. Per risolvere questo problema, ricompilare tutti i file che includono la funzione in pacchetto.

  • Questo errore può verificarsi se il simbolo viene definito in modo diverso in due oggetti membro in librerie diverse e vengono utilizzati entrambi gli oggetti membro. Un modo per risolvere questo problema quando le librerie sono collegate in modo statico consiste nell'usare l'oggetto membro da una sola libreria e includere prima tale libreria nella riga di comando del linker. Per usare entrambi i simboli, è necessario creare un modo per distinguerli. Ad esempio, se è possibile compilare le librerie dall'origine, è possibile eseguire il wrapping di ogni libreria in uno spazio dei nomi univoco. In alternativa, è possibile creare una nuova libreria wrapper che usa nomi univoci per eseguire il wrapping dei riferimenti a una delle librerie originali, collegare la nuova libreria alla libreria originale, quindi collegare il file eseguibile alla nuova libreria anziché alla libreria originale.

  • Questo errore può verificarsi se una extern const variabile viene definita due volte e ha un valore diverso in ogni definizione. Per risolvere questo problema, definire la costante una sola volta o usare spazi dei nomi o enum class definizioni per distinguere le costanti.

  • Questo errore può verificarsi se si usa uuid.lib in combinazione con altri file lib che definiscono GUID, ad esempio oledb.lib e adsiid.lib. Ad esempio:

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

    Per risolvere questo problema, aggiungere /FORCE:MULTIPLE alle opzioni della riga di comando del linker e assicurarsi che uuid.lib sia la prima libreria a cui si fa riferimento.