Condividi tramite


Errore degli strumenti del linker LNK2019

unresolved external symbol 'symbol' a cui si fa riferimento nella funzione 'function'

Il codice compilato per la funzione esegue un riferimento o una chiamata al simbolo, ma il linker non riesce a trovare la definizione del simbolo in nessuna delle librerie o dei file oggetto.

Questo messaggio di errore è seguito da un errore irreversibile LNK1120. Per correggere l'errore LNK1120, è necessario correggere prima tutti gli errori di LNK2001 e LNK2019.

Possibili cause

Esistono molti modi per ottenere questo errore. Tutti implicano un riferimento a una funzione o a una variabile per cui il linker non è riuscito a risolvere o a trovare una definizione. Il compilatore può identificare quando un simbolo non è dichiarato, ma non può indicare quando il simbolo non è definito. Il motivo è che la definizione potrebbe trovarsi in un file o una libreria di origine diversi. Se si fa riferimento a un simbolo ma non viene mai definito, il linker genera un errore di simbolo al non risolto extern.

Di seguito sono riportati alcuni problemi comuni che causano l'errore LNK2019:

Il file di origine che contiene la definizione del simbolo non viene compilato

In Visual Studio verificare che il file di origine che definisce il simbolo venga compilato come parte del progetto. Controllare la directory di output di compilazione intermedia per trovare un file .obj corrispondente. Se il file di origine non è compilato, fare clic con il pulsante destro del mouse sul file in Esplora soluzioni e scegliere Proprietà per controllare le proprietà del file. La pagina Proprietà>di configurazione Generale deve visualizzare un tipo di elemento del compilatore C/C++. Nella riga di comando verificare che il file di origine contenente la definizione sia compilato.

Il file oggetto o la libreria che contiene la definizione del simbolo non è collegato

In Visual Studio verificare che il file o la libreria dell'oggetto che contiene la definizione del simbolo sia collegato come parte del progetto. Nella riga di comando verificare che l'elenco dei file da collegare includa il file oggetto o la libreria.

La dichiarazione del simbolo non viene digitata come la definizione del simbolo

Verificare di usare l'ortografia e la maiuscola corrette sia nella dichiarazione che nella definizione e ovunque venga usato o chiamato il simbolo.

Viene usata una funzione, ma il tipo o il numero dei parametri non corrispondono alla definizione della funzione

La dichiarazione della funzione deve corrispondere alla definizione. Assicurarsi che la chiamata di funzione corrisponda alla dichiarazione e che la dichiarazione corrisponda alla definizione. Il codice che richiama i modelli di funzione deve avere anche dichiarazioni di modello di funzione corrispondenti che includono gli stessi parametri del modello della definizione. Per un esempio di mancata corrispondenza di una dichiarazione di modello, vedere l'esempio LNK2019e.cpp nella sezione Esempi.

Una funzione o una variabile viene dichiarata ma non definita

LNK2019 possono verificarsi quando esiste una dichiarazione in un file di intestazione, ma non viene implementata alcuna definizione corrispondente. Per le funzioni membro o static i membri dati, l'implementazione deve includere il selettore dell'ambito della classe. Per un esempio, vedere Missing Function Body or Variable.

La convenzione di chiamata è diversa tra la dichiarazione di funzione e la definizione della funzione

Alcune convenzioni di chiamata (__cdecl, __stdcall, __fastcalle __vectorcall) vengono codificate come parte del nome decorato. Assicurarsi che la convenzione di chiamata sia la stessa.

Un simbolo viene definito in un file C, ma dichiarato senza usare extern "C" in un file C++

Un file compilato come C crea nomi decorati per i simboli diversi dai nomi decorati per gli stessi simboli dichiarati in un file C++, a meno che non si usi un extern "C" modificatore. Assicurarsi che la dichiarazione corrisponda al collegamento di compilazione per ogni simbolo. Analogamente, se si definisce un simbolo in un file di C++ che verrà usato da un programma C, usare extern "C" nella definizione.

Un simbolo viene definito come static e quindi fatto riferimento successivamente all'esterno del file

In C++, a differenza di C, le formiche globali consthanno static un collegamento. Per ovviare a questa limitazione, è possibile includere le const inizializzazioni in un file di intestazione e includere tale intestazione nei file .cpp oppure è possibile impostare la variabile come nonconst formica e usare un constriferimento formica per accedervi.

Un static membro di una classe non è definito

Un static membro della classe deve avere una definizione univoca oppure viola la regola di definizione singola. Un static membro della classe che non può essere definito inline deve essere definito in un file di origine usando il nome completo. Se non è definito affatto, il linker genera LNK2019.

Una dipendenza di compilazione viene definita solo come dipendenza del progetto nella soluzione

Nelle versioni precedenti di Visual Studio questo livello di dipendenza era sufficiente. Tuttavia, a partire da Visual Studio 2010, Visual Studio richiede un riferimento da progetto a progetto. Se il progetto non ha un riferimento da progetto a progetto, è possibile che venga visualizzato questo errore del linker. Aggiungere un riferimento da progetto a progetto per risolvere il problema.

Non è definito un punto di ingresso

Il codice dell'applicazione deve definire un punto di ingresso appropriato: main o wmain per le applicazioni console e WinMain per wWinMain le applicazioni Windows. Per altre informazioni, vedere main funzioni e argomenti della riga di comando o WinMain funzione. Per usare un punto di ingresso personalizzato, specificare l'opzione /ENTRY del linker (Simbolo punto di ingresso).

Si compila un'applicazione console usando le impostazioni per un'applicazione Windows

Se il messaggio di errore è simile al simbolo non risolto externa cui fa riferimento nella funzione function_name, collegarlo usando /SUBSYSTEM:CONSOLE anziché /SUBSYSTEM:WINDOWS.WinMain Per altre informazioni su questa impostazione e per istruzioni su come impostare questa proprietà in Visual Studio, vedere /SUBSYSTEM (Specificare il sottosistema).

Le librerie e i file oggetto collegati al codice devono essere compilati per la stessa architettura del codice. Assicurarsi che le librerie a cui i riferimenti al progetto siano compilati per la stessa architettura del progetto. Assicurarsi che la /LIBPATH proprietà o Directory librerie aggiuntive punti alle librerie compilate per l'architettura corretta.

Si usano diverse opzioni del compilatore per l'inlining delle funzioni in file di origine diversi

L'uso delle funzioni inline definite nei file cpp e la combinazione di opzioni del compilatore per l'inline delle funzioni in file di origine diversi può causare l'errore LNK2019. Per altre informazioni, vedere Function Inlining Problems.

Le variabili automatiche non rientrano nell'ambito

Le variabili automatiche (ambito funzione) possono essere usate solo nell'ambito di tale funzione. Queste variabili non possono essere dichiarate come extern e usate in altri file di origine. Per un esempio, vedere Automatic (Function Scope) Variables.

È possibile chiamare funzioni intrinseche o passare tipi di argomento a funzioni intrinseche non supportate nell'architettura di destinazione

Ad esempio, se si usa un AVX2 valore intrinseco, ma non si specifica l'opzione del /ARCH:AVX2 compilatore, il compilatore presuppone che l'intrinseco sia una externfunzione al. Anziché generare un'istruzione inline, il compilatore genera una chiamata a un externsimbolo al con lo stesso nome dell'oggetto intrinseco. Quando il linker prova a cercare la definizione di questa funzione mancante, viene generato l'errore LNK2019. Assicurarsi di usare solo oggetti intrinseci e tipi supportati dall'architettura di destinazione.

È possibile combinare codice che usa codice nativo wchar_t con codice che non è

Il lavoro di conformità al linguaggio C++ eseguito in Visual Studio 2005 ha reso wchar_t un tipo nativo per impostazione predefinita. Se non tutti i file sono stati compilati usando le stesse /Zc:wchar_t impostazioni, i riferimenti di tipo potrebbero non risolversi in tipi compatibili. Assicurarsi che wchar_t i tipi in tutti i file di libreria e oggetti siano compatibili. Aggiornare da un wchar_t typedef o usare /Zc coerente :wchar_t impostazioni durante la compilazione.

Una static libreria compilata usando una versione di Visual Studio precedente a Visual Studio 2015 potrebbe causare errori LNK2019 quando è collegato a UCRT. I file <stdio.h>di intestazione UCRT , <conio.h>e <wchar.h>ora definiscono molte *printf* varianti e *scanf* come inline funzioni. Le funzioni inlined vengono implementate da un set più piccolo di funzioni comuni. Le singole esportazioni per le funzioni inlined non sono disponibili nelle librerie UCRT standard, che esportano solo le funzioni comuni. Esistono due modi per risolvere questo problema. Il metodo consigliato consiste nel ricompilare la libreria legacy con la versione corrente di Visual Studio. Assicurarsi che il codice della libreria usi le intestazioni standard per le definizioni delle *printf* funzioni e *scanf* che hanno causato gli errori. Un'altra opzione per una libreria legacy che non è possibile ricompilare consiste nell'aggiungere legacy_stdio_definitions.lib all'elenco di librerie collegate. Questo file di libreria fornisce simboli per le *printf* funzioni e *scanf* inlinedi nelle intestazioni UCRT. Per altre informazioni, vedere la sezione Librerie in Panoramica dei potenziali problemi di aggiornamento.

Problemi di libreria di terze parti e vcpkg

Se viene visualizzato questo errore quando si tenta di configurare una libreria di terze parti come parte della compilazione, provare a usare vcpkg. vcpkg è una gestione pacchetti C++ che usa gli strumenti di Visual Studio esistenti per installare e compilare la libreria. vcpkg supporta un elenco di librerie di terze parti di grandi dimensioni e in crescita. Imposta tutte le proprietà di configurazione e le dipendenze necessarie per le compilazioni riuscite come parte del progetto.

Strumenti di diagnosi

A volte è difficile capire perché il linker non riesce a trovare una definizione di simbolo particolare. Spesso il problema è che non è stato incluso il codice che contiene la definizione nella compilazione. In alternativa, le opzioni di compilazione hanno creato nomi decorati diversi per externi simboli al. Sono disponibili diversi strumenti e opzioni che consentono di diagnosticare LNK2019 errori.

  • L'opzione /VERBOSE del linker consente di determinare quali file fanno riferimento al linker. Questa opzione consente di verificare se il file che contiene la definizione del simbolo è incluso nella compilazione.

  • Le /EXPORTS opzioni e /SYMBOLS dell'utilità DUMPBIN consentono di individuare i simboli definiti nei file di .dll e di oggetto o libreria. Assicurarsi che i nomi decorati esportati corrispondano ai nomi decorati cercati dal linker.

  • L'utilità UNDNAME può visualizzare il simbolo equivalente non dichiarato external per un nome decorato.

Esempi

Di seguito sono riportati alcuni esempi di codice che causano errori LNK2019, insieme alle informazioni su come correggere gli errori.

Un simbolo viene dichiarato ma non definito

In questo esempio una externvariabile al viene dichiarata ma non definita:

// LNK2019.cpp
// Compile by using: cl /EHsc /W4 LNK2019.cpp
// LNK2019 expected
extern char B[100];   // B isn't available to the linker
int main() {
   B[0] = ' ';   // LNK2019
}

Ecco un altro esempio in cui una variabile e una funzione vengono dichiarate come extern ma non viene fornita alcuna definizione:

// LNK2019c.cpp
// Compile by using: cl /EHsc LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
   i++;
   g();
}
int main() {}

A meno che i e g non siano definiti in uno dei file inclusi nella compilazione, il linker genera LNK2019. È possibile correggere gli errori includendo il file del codice sorgente che contiene le definizioni come parte della compilazione. In alternativa, è possibile passare .obj file o .lib file che contengono le definizioni al linker.

Un static membro dati viene dichiarato ma non definito

LNK2019 possono verificarsi anche quando un static membro dati viene dichiarato ma non definito. L'esempio seguente genera l'errore LNK2019 e mostra come risolverlo.

// LNK2019b.cpp
// Compile by using: cl /EHsc LNK2019b.cpp
// LNK2019 expected
struct C {
   static int s;
};

// Uncomment the following line to fix the error.
// int C::s;

int main() {
   C c;
   C::s = 1;
}

I parametri di dichiarazione non corrispondono alla definizione

Il codice che richiama i modelli di funzione deve avere dichiarazioni di modello di funzione corrispondenti. Le dichiarazioni devono includere gli stessi parametri modello della definizione. L'esempio seguente genera l'errore LNK2019 per un operatore definito dall'utente e mostra come risolverlo.

// LNK2019e.cpp
// compile by using: cl /EHsc LNK2019e.cpp
// LNK2019 expected
#include <iostream>
using namespace std;

template<class T> class
Test {
   // The operator<< declaration doesn't match the definition below:
   friend ostream& operator<<(ostream&, Test&);
   // To fix, replace the line above with the following:
   // 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;   // LNK2019 unresolved external
}

Definizioni di tipi incoerenti wchar_t

In questo esempio viene creata una DLL con un'esportazione che usa WCHAR, che viene risolta in wchar_t.

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

L'esempio successivo usa la DLL nell'esempio precedente e genera LNK2019 perché i tipi unsigned short* e WCHAR* non sono uguali.

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

int main() {
   func(0);
}

Per correggere l'errore, passare unsigned short a wchar_t o WCHARoppure compilare LNK2019g.cpp usando /Zc:wchar_t-.

Vedi anche

Per altre informazioni sulle possibili cause e soluzioni per LNK2019, LNK2001 e errori di LNK1120, vedere la domanda Stack Overflow: What is an undefined reference/unresolved external symbol error and how do I fix it?.