Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
olöst extern symbol 'symbol' refererad i funktion 'function'
Den kompilerade koden för funktionen gör en referens eller ett anrop till symbolen, men länkaren kan inte hitta symboldefinitionen i något av biblioteken eller objektfilerna.
Det här felmeddelandet följs av ett allvarligt fel LNK1120. Om du vill åtgärda fel LNK1120 måste du åtgärda alla LNK2001 och LNK2019 fel först.
Möjliga orsaker
Det finns många sätt att få det här felet. Alla involverar en referens till en funktion eller variabel som länkaren inte kunde lösa eller hitta en definition för. Kompilatorn kan identifiera när en symbol inte deklareras, men det går inte att se när symbolen inte har definierats. Det beror på att definitionen kan finnas i en annan källfil eller ett annat bibliotek. Om en symbol refereras till men aldrig definieras genererar länkaren ett olöst externt symbolfel.
Här följer några vanliga problem som orsakar LNK2019:
Källfilen som innehåller symboldefinitionen kompileras inte
I Visual Studio kontrollerar du att källfilen som definierar symbolen kompileras som en del av projektet. Kontrollera katalogen för mellanliggande bygg för att hitta en matchande .obj-fil. Om källfilen inte kompileras högerklickar du på filen i Solution Explorer och väljer sedan Egenskaper för att kontrollera filens egenskaper. Sidan Allmänna konfigurationsegenskaper> bör visa en objekttyp av C/C++-kompilator. På kommandoraden kontrollerar du att källfilen som innehåller definitionen är kompilerad.
Objektfilen eller biblioteket som innehåller definitionen av symbolen är inte länkad
I Visual Studio kontrollerar du att objektfilen eller biblioteket som innehåller symboldefinitionen är länkad som en del av projektet. På kommandoraden kontrollerar du att listan över filer som ska länkas innehåller objektfilen eller biblioteket.
Symboldeklarationen stavas inte på samma sätt som symbolens definition
Kontrollera att du använder rätt stavning och versaler i både deklarationen och definitionen, och var symbolen används eller anropas.
En funktion används men typen eller antalet parametrar matchar inte funktionsdefinitionen
Funktionsdeklarationen måste matcha definitionen. Kontrollera att funktionsanropet matchar deklarationen och att deklarationen matchar definitionen. Kod som anropar funktionsmallar måste också ha matchande funktionsmalldeklarationer som innehåller samma mallparametrar som definitionen. Ett exempel på ett felmatchat malldeklarationsfel finns i exempel LNK2019e.cpp i avsnittet Exempel.
En funktion eller variabel deklareras men definieras inte
LNK2019 kan inträffa när det finns en deklaration i en rubrikfil, men ingen matchande definition implementeras. För medlemsfunktioner eller static datamedlemmar måste implementeringen innehålla klassens selektor. Ett exempel finns i Saknas funktionstext eller variabel.
Anropskonventionen skiljer sig mellan funktionsdeklarationen och funktionsdefinitionen
Vissa anropskonventioner (__cdecl
, __stdcall
, __fastcall
och __vectorcall
) kodas som en del av det dekorerade namnet. Kontrollera att anropskonventionen är densamma.
En symbol definieras i en C-fil, men deklareras utan att använda extern "C"
i en C++-fil
En fil som kompileras som C skapar dekorerade namn för symboler som skiljer sig från de dekorerade namnen för samma symboler som deklareras i en C++-fil, såvida du inte använder en extern "C"
modifierare. Kontrollera att deklarationen matchar kompileringslänkaget för varje symbol. Om du på samma sätt definierar en symbol i en C++-fil som ska användas av ett C-program använder du extern "C"
i definitionen.
En symbol definieras som static och refereras sedan senare utanför filen
I C++ har globala konstanter till skillnad från C static
koppling. För att komma runt den här begränsningen const
kan du inkludera initieringarna i en rubrikfil och inkludera rubriken i dina .cpp filer, eller så kan du göra variabeln icke-konstant och använda en konstant referens för att komma åt den.
En static medlem i en klass har inte definierats
En static klassmedlem måste ha en unik definition, annars bryter den mot regeln med en definition. En static klassmedlem som inte kan definieras inline måste definieras i en enda källfil med hjälp av dess fullständigt kvalificerade namn. Om den inte har definierats alls genererar länkaren LNK2019.
Ett byggberoende definieras endast som ett projektberoende i lösningen
I tidigare versioner av Visual Studio var den här beroendenivån tillräcklig. Men från och med Visual Studio 2010 kräver Visual Studio en referens för projekt till projekt. Om projektet inte har någon referens för projekt till projekt kan du få det här länkfelet. Lägg till en projekt-till-projekt-referens för att åtgärda den.
En startpunkt har inte definierats
Programkoden måste definiera en lämplig startpunkt: main
eller wmain
för konsolprogram och WinMain
eller wWinMain
för Windows-program. Mer information finns i main
funktions- och kommandoradsargument eller WinMain
funktion. Om du vill använda en anpassad startpunkt anger du länkalternativet /ENTRY
(Entry-Point Symbol ).
Du skapar ett konsolprogram med hjälp av inställningar för ett Windows-program
Om felmeddelandet liknar olöst extern symbol WinMain som refereras till i funktionenfunction_name, länkar du med /SUBSYSTEM:CONSOLE
i stället för /SUBSYSTEM:WINDOWS
. Mer information om den här inställningen och anvisningar om hur du anger den här egenskapen i Visual Studio /SUBSYSTEM
finns i (Ange undersystem).
Du försöker länka 64-bitarsbibliotek till 32-bitarskod eller 32-bitarsbibliotek till 64-bitarskod
Bibliotek och objektfiler som är länkade till koden måste kompileras för samma arkitektur som koden. Kontrollera att biblioteken som projektreferenserna hänvisar till är kompilerade för samma arkitektur som projektet. Kontrollera att /LIBPATH
egenskapen eller Ytterligare bibliotekskataloger pekar på bibliotek som skapats för rätt arkitektur.
Du använder olika kompilatoralternativ för funktionsinslinering i olika källfiler
Om du använder inline-funktioner definierade i cpp-filer och kombinerar funktionen inlining med kompilatoralternativ i olika källfiler kan det orsaka felet LNK2019. Mer information finns i Problem med funktionslinering.
Du använder automatiska variabler utanför deras omfång
Automatiska variabler (funktionsomfång) kan bara användas i funktionens omfång. Dessa variabler kan inte deklareras extern
och användas i andra källfiler. Ett exempel finns i Automatiska variabler (funktionsomfång).
Du anropar inbyggda funktioner eller skickar argumenttyper till inbyggda funktioner som inte stöds i målarkitekturen
Om du till exempel använder ett AVX2 inbyggt, men inte anger /ARCH:AVX2
kompileringsalternativet, förutsätter kompilatorn att det inbyggda är en extern funktion. I stället för att generera en infogad instruktion genererar kompilatorn ett anrop till en extern symbol med samma namn som den inbyggda. När länkaren försöker hitta definitionen av denna saknade funktion genererar den LNK2019. Se till att du bara använder inbyggda egenskaper och typer som stöds av målarkitekturen.
Du blandar kod som använder inbyggt wchar_t
med kod som inte
C++-språkefterlevnadsarbete som utfördes i Visual Studio 2005 gjorde wchar_t
till en inbyggd typ som standard. Om inte alla filer har kompilerats med samma /Zc:wchar_t
inställningar kanske typreferenser inte matchar kompatibla typer. Kontrollera att wchar_t
typerna i alla biblioteks- och objektfiler är kompatibla. Uppdatera från en wchar_t
typedef eller använd konsekventa /Zc:wchar_t -inställningar när du kompilerar.
Du får fel för printf
och scanf
funktioner när du länkar ett äldre static bibliotek
Ett static bibliotek som skapades med en version av Visual Studio före Visual Studio 2015 kan orsaka LNK2019 fel när det är länkat till UCRT. UCRT-huvudfilerna <stdio.h>
, <conio.h>
och <wchar.h>
definierar nu många printf
och scanf
varianter som inline
funktioner. Inlinjerade funktioner implementeras av en begränsad uppsättning vanliga funktioner. Enskilda exporter för inlined-funktionerna är inte tillgängliga i standardbiblioteken för UCRT, som endast exporterar de vanliga funktionerna. Det finns ett par sätt att lösa problemet. Den metod vi rekommenderar är att återskapa det äldre biblioteket med din aktuella version av Visual Studio. Kontrollera att bibliotekskoden använder standardhuvudena för definitionerna av funktionerna printf
och scanf
som orsakade felen. Ett annat alternativ för ett äldre bibliotek som du inte kan återskapa är att lägga legacy_stdio_definitions.lib
till i listan över bibliotek som du länkar till. Den här biblioteksfilen innehåller symboler för funktionerna printf
och scanf
som är inlindade i UCRT-huvudena. Mer information finns i avsnittet Bibliotek i Översikt över potentiella uppgraderingsproblem.
Biblioteksproblem från tredje part och vcpkg
Om du ser det här felet när du försöker konfigurera ett bibliotek från tredje part som en del av bygget bör du överväga att använda vcpkg. vcpkg är en C++-pakethanterare som använder dina befintliga Visual Studio-verktyg för att installera och skapa biblioteket. vcpkg stöder en stor och växande lista över bibliotek från tredje part. Den anger alla konfigurationsegenskaper och beroenden som krävs för lyckade versioner som en del av projektet.
Diagnosverktyg
Ibland är det svårt att avgöra varför länkaren inte kan hitta en viss symboldefinition. Problemet är ofta att du inte har inkluderat koden som innehåller definitionen i din version. Eller så har byggalternativ skapat olika dekorerade namn för externa symboler. Det finns flera verktyg och alternativ som kan hjälpa dig att diagnostisera LNK2019 fel.
Länkalternativet
/VERBOSE
kan hjälpa dig att avgöra vilka filer länkaren refererar till. Det här alternativet kan hjälpa dig att kontrollera om filen som innehåller symboldefinitionen ingår i din version.Verktygets
/EXPORTS
alternativ/SYMBOLS
och DUMPBIN kan hjälpa dig att identifiera vilka symboler som definieras i dina .dll- och objekt- eller biblioteksfiler. Kontrollera att de exporterade dekorerade namnen överensstämmer med de dekorerade namn som länkaren letar efter.Programmet UNDNAME kan visa den motsvarande odekorerade externa symbolen för ett dekorerat namn.
Exempel
Här följer flera exempel på kod som orsakar LNK2019 fel, tillsammans med information om hur du åtgärdar felen.
En symbol deklareras men definieras inte
I det här exemplet deklareras en extern variabel men definieras inte:
// 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
}
Här är ett annat exempel där en variabel och funktion deklareras som extern
men ingen definition anges:
// LNK2019c.cpp
// Compile by using: cl /EHsc LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
i++;
g();
}
int main() {}
Om inte i
och g
definieras i en av filerna som ingår i versionen genererar länkaren LNK2019. Du kan åtgärda felen genom att inkludera källkodsfilen som innehåller definitionerna som en del av kompilering. Du kan också skicka .obj
filer eller .lib
filer som innehåller definitionerna till länkaren.
En static datamedlem deklareras men definieras inte
LNK2019 kan också inträffa när en static datamedlem deklareras men inte definieras. Följande exempel genererar LNK2019 och visar hur du åtgärdar det.
// 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;
}
Deklarationsparametrar matchar inte definitionen
Kod som anropar funktionsmallar måste ha matchande funktionsmalldeklarationer. Deklarationer måste innehålla samma mallparametrar som definitionen. Följande exempel genererar LNK2019 för en användardefinierad operator och visar hur du fixar det.
// 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
}
Inkonsekventa wchar_t typdefinitioner
Det här exemplet skapar en DLL som har en export som använder WCHAR
, som leder till wchar_t
.
// LNK2019g.cpp
// compile with: cl /EHsc /LD LNK2019g.cpp
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}
Nästa exempel använder DLL i föregående exempel och genererar LNK2019 eftersom typerna unsigned short*
och WCHAR*
inte är desamma.
// LNK2019h.cpp
// compile by using: cl /EHsc LNK2019h LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);
int main() {
func(0);
}
Åtgärda det här felet genom att ändra unsigned short
till wchar_t
eller WCHAR
eller kompilera LNK2019g.cpp med hjälp /Zc:wchar_t-
av .
Se även
Mer information om möjliga orsaker och lösningar för LNK2019, LNK2001 och LNK1120 fel finns i Stack Overflow-frågan: What is an undefined reference/unresolved external symbol error and how do I fix it?
.