Chyba linkerů LNK2019
nevyřešený externí symbol "symbol" odkazovaný ve funkci "function"
Zkompilovaný kód funkce vytváří odkaz nebo volání symbolu, ale linker nemůže najít definici symbolu v žádné knihovně nebo objektových souborech.
Za touto chybovou zprávou následuje závažná chyba LNK1120. Pokud chcete opravit chyby LNK1120, musíte nejprve opravit všechny chyby LNK2001 a LNK2019.
Možné příčiny
Tato chyba se může zobrazit mnoha způsoby. Všechny zahrnují odkaz na funkci nebo proměnnou, kterou linker nemohl rozpoznat nebo najít definici. Kompilátor dokáže identifikovat, kdy není symbol deklarován, ale nedokáže zjistit, kdy není symbol definovaný. Je to proto, že definice může být v jiném zdrojovém souboru nebo knihovně. Pokud se na symbol odkazuje, ale nikdy není definován, linker vygeneruje nevyřešenou chybu externího symbolu.
Tady jsou některé běžné problémy, které způsobují LNK2019:
Zdrojový soubor, který obsahuje definici symbolu, není zkompilován.
V sadě Visual Studio se ujistěte, že se zdrojový soubor, který definuje symbol, zkompiluje jako součást projektu. Zkontrolujte výstupní adresář zprostředkujícího sestavení pro odpovídající soubor .obj. Pokud zdrojový soubor není zkompilován, klikněte pravým tlačítkem myši na soubor v Průzkumník řešení a potom zvolte Vlastnosti a zkontrolujte vlastnosti souboru. Na stránce Obecné vlastnosti>konfigurace by se měl zobrazit typ položky kompilátoru C/C++. Na příkazovém řádku se ujistěte, že je zdrojový soubor obsahující definici zkompilován.
Soubor objektu nebo knihovna obsahující definici symbolu není propojený.
V sadě Visual Studio se ujistěte, že je soubor objektu nebo knihovna obsahující definici symbolu propojená jako součást projektu. Na příkazovém řádku se ujistěte, že seznam souborů, které chcete propojit, obsahuje soubor objektu nebo knihovnu.
Deklarace symbolu není napsaná stejně jako definice symbolu.
Ověřte, že v deklaraci i definici použijete správnou pravopisnou a velká písmena a všude tam, kde se symbol používá nebo volá.
Použije se funkce, ale typ nebo počet parametrů neodpovídá definici funkce.
Deklarace funkce se musí shodovat s definicí. Ujistěte se, že volání funkce odpovídá deklaraci a že deklarace odpovídá definici. Kód, který vyvolá šablony funkcí, musí mít také odpovídající deklarace šablony funkce, které obsahují stejné parametry šablony jako definice. Příklad neshody deklarací šablony najdete v ukázkové LNK2019e.cpp v části Příklady.
Funkce nebo proměnná je deklarována, ale není definována.
LNK2019 může dojít v případě, že deklarace existuje v souboru hlaviček, ale není implementována žádná odpovídající definice. Pro členské funkce nebo static datové členy musí implementace obsahovat selektor oboru třídy. Příklad najdete v tématu Chybějící tělo funkce nebo proměnná.
Konvence volání se liší mezi deklarací funkce a definicí funkce.
Některé konvence volání (__cdecl
, __stdcall
, __fastcall
a __vectorcall
) jsou kódovány jako součást zdobeného názvu. Ujistěte se, že konvence volání je stejná.
Symbol je definován v souboru jazyka C, ale deklarován bez použití extern "C"
v souboru C++
Soubor, který je zkompilovaný jako C, vytváří upravené názvy symbols , které se liší od zdobených názvů pro stejný symbols deklarovaný v souboru C++, pokud nepoužíváte extern "C"
modifikátor. Ujistěte se, že deklarace odpovídá propojení kompilace pro každý symbol. Podobně pokud definujete symbol v souboru C++, který bude používán programem jazyka C, použijte extern "C"
v definici.
Symbol je definován jako static a později odkazován mimo soubor.
Na rozdíl od jazyka C++ mají static
globální konstanty propojení. Chcete-li toto omezení obejít, můžete zahrnout const
inicializace do souboru záhlaví a zahrnout toto záhlaví do .cpp souborů, nebo můžete proměnnou nastavit jako nestájnou a použít k němu konstantní odkaz.
Není static definován člen třídy.
Člen static třídy musí mít jedinečnou definici nebo porušuje pravidlo s jednou definicí. Člen static třídy, který nelze definovat vloženého souboru, musí být definován v jednom zdrojovém souboru pomocí jeho plně kvalifikovaného názvu. Pokud vůbec není definován, linker vygeneruje LNK2019.
Závislost sestavení je definována pouze jako závislost projektu v řešení.
V dřívějších verzích sady Visual Studio byla tato úroveň závislosti dostatečná. Počínaje sadou Visual Studio 2010 ale Visual Studio vyžaduje odkaz na projekt-projekt. Pokud váš projekt nemá odkaz na projekt-projekt, může se zobrazit tato chyba linkeru. Přidejte odkaz na projekt-projekt, který ho opraví.
Vstupní bod není definován.
Kód aplikace musí definovat odpovídající vstupní bod: main
nebo wmain
pro konzolové aplikace nebo WinMain
wWinMain
pro aplikace systému Windows. Další informace najdete v tématu main
funkce a argumenty příkazového řádku nebo WinMain
funkce. Pokud chcete použít vlastní vstupní bod, zadejte možnost linkeru /ENTRY
(Symbol vstupního bodu).
Sestavíte konzolovou aplikaci pomocí nastavení pro aplikaci pro Windows.
Pokud je chybová zpráva podobná nevyřešenému externímu symbolu WinMain odkazovanému ve funkci function_name, použijte odkaz místo /SUBSYSTEM:CONSOLE
/SUBSYSTEM:WINDOWS
. Další informace o tomto nastavení a pokyny k nastavení této vlastnosti v sadě Visual Studio najdete v tématu /SUBSYSTEM
(Určení subsystému).
Pokusíte se propojit 64bitové knihovny s 32bitovým kódem nebo 32bitovými knihovnami na 64bitový kód.
Knihovny a soubory objektů propojené s vaším kódem musí být zkompilovány pro stejnou architekturu jako váš kód. Ujistěte se, že jsou knihovny, na které odkazuje váš projekt, zkompilovány pro stejnou architekturu jako váš projekt. Ujistěte se, /LIBPATH
že vlastnost nebo další adresáře knihovny odkazuje na knihovny vytvořené pro správnou architekturu.
Pro vkládání funkcí v různých zdrojových souborech se používají různé možnosti kompilátoru.
Použití inlinovaných funkcí definovaných v .cpp souborech a kombinování možností inliningu funkcí v různých zdrojových souborech může způsobit LNK2019. Další informace naleznete v tématu Funkce Inlining Problémy.
Použijete automatické proměnné mimo jejich obor.
Automatické proměnné (obor funkce) lze použít pouze v oboru této funkce. Tyto proměnné nelze deklarovat extern
a používat v jiných zdrojových souborech. Příklad najdete v tématu Automatické proměnné (obor funkce).
Volat vnitřní funkce nebo předat typy argumentů vnitřní funkce, které nejsou podporovány v cílové architektuře
Pokud například použijete AVX2 vnitřní, ale nezadáte možnost kompilátoru /ARCH:AVX2
, kompilátor předpokládá, že vnitřní je externí funkce. Místo vygenerování vložené instrukce kompilátor vygeneruje volání externího symbolu se stejným názvem jako vnitřní. Když se linker pokusí najít definici této chybějící funkce, vygeneruje LNK2019. Ujistěte se, že používáte pouze vnitřní objekty a typy podporované cílovou architekturou.
Kód, který používá nativní wchar_t
kód, který nepoužívá
Práce v souladu jazyka C++, která byla provedena v sadě Visual Studio 2005, byla wchar_t
ve výchozím nastavení nativním typem. Pokud nebyly všechny soubory zkompilovány pomocí stejného /Zc:wchar_t
nastavení, odkazy na typy nemusí být přeloženy na kompatibilní typy. Ujistěte se, že wchar_t
jsou typy ve všech knihovnách a souborech objektů kompatibilní. Buď aktualizujte z wchar_t
typedef, nebo při kompilaci použijte konzistentní nastavení /Zc:wchar_t
Při propojení starší static knihovny dojde k *printf*
chybám a *scanf*
funkcím.
Knihovna static vytvořená pomocí verze sady Visual Studio před sadou Visual Studio 2015 může způsobit chyby LNK2019 při propojení s UCRT. Soubory <stdio.h>
hlaviček UCRT a <conio.h>
<wchar.h>
nyní definují mnoho *printf*
a *scanf*
varianty jako inline
funkce. Vložené funkce jsou implementovány menší sadou běžných funkcí. Jednotlivec exports pro vložené funkce není k dispozici ve standardních knihovnách UCRT, které exportují pouze běžné funkce. Tento problém můžete vyřešit několika způsoby. Doporučujeme znovu sestavit starší knihovnu s aktuální verzí sady Visual Studio. Ujistěte se, že kód knihovny používá standardní hlavičky pro definice *printf*
funkcí a *scanf*
funkcí, které způsobily chyby. Další možností pro starší knihovnu, kterou nemůžete znovu sestavit, je přidat legacy_stdio_definitions.lib
do seznamu knihoven, které propočítáte. Tento soubor knihovny poskytuje symbols *printf*
*scanf*
funkce, které jsou vloženy do hlaviček UCRT. Další informace najdete v části Knihovny v tématu Přehled potenciálních problémů s upgradem.
Problémy s knihovnou třetích stran a vcpkg
Pokud se při pokusu o konfiguraci knihovny třetí strany v rámci sestavení zobrazí tato chyba, zvažte použití nástroje vcpkg. vcpkg je správce balíčků C++ , který k instalaci a sestavení knihovny používá stávající nástroje sady Visual Studio. vcpkg podporuje velký a rostoucí seznam knihoven třetích stran. Nastaví všechny vlastnosti konfigurace a závislosti potřebné pro úspěšné sestavení v rámci projektu.
Diagnostické nástroje
Někdy je obtížné zjistit, proč linker nemůže najít konkrétní definici symbolu. Často je problém, že jste nezahrnuli kód, který obsahuje definici v sestavení. Nebo možnosti sestavení vytvořily různé zdobené názvy pro externí symbols. Existuje několik nástrojů a možností, které vám můžou pomoct s diagnostikou chyb LNK2019.
Možnost
/VERBOSE
linkeru vám může pomoct určit soubory, na které odkazy linker odkazuje. Tato možnost vám může pomoct ověřit, jestli je soubor, který obsahuje definici symbolu, součástí sestavení.Možnosti
/EXPORTS
nástroje/SYMBOLS
DUMPBIN vám můžou pomoct zjistit, které symbols jsou definovány ve vašich .dll a souborech objektů nebo knihoven. Ujistěte se, že exportované zdobené názvy odpovídají zdobeným názvům, které linker hledá.Nástroj UNDNAME vám může ukázat ekvivalentní nedekódovaný externí symbol pro zdobený název.
Příklady
Tady je několik příkladů kódu, který způsobuje chyby LNK2019 společně s informacemi o tom, jak chyby opravit.
Symbol je deklarován, ale není definován.
V tomto příkladu je externí proměnná deklarována, ale není definována:
// 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
}
Tady je další příklad, ve kterém jsou proměnné a funkce deklarovány jako extern
definice, ale není k dispozici žádná definice:
// LNK2019c.cpp
// Compile by using: cl /EHsc LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
i++;
g();
}
int main() {}
Pokud i
nejsou g
definovány v jednom ze souborů zahrnutých v sestavení, linker vygeneruje LNK2019. Chyby můžete opravit zahrnutím souboru zdrojového kódu, který obsahuje definice jako součást kompilace. Alternativně můžete předat .obj
soubory nebo .lib
soubory, které obsahují definice linkeru.
Datový static člen je deklarován, ale není definován.
LNK2019 může dojít také v případě, že static je datový člen deklarován, ale není definován. Následující ukázka vygeneruje LNK2019 a ukazuje, jak ji opravit.
// 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;
}
Parametry deklarace neodpovídají definici
Kód, který vyvolá šablony funkcí, musí mít odpovídající deklarace šablony funkce. Deklarace musí obsahovat stejné parametry šablony jako definice. Následující ukázka vygeneruje LNK2019 u uživatelem definovaného operátoru a ukazuje, jak ho opravit.
// 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
}
Nekonzistentní wchar_t definice typu
Tato ukázka vytvoří knihovnu DLL s exportem, který používá WCHAR
, který se překládá na wchar_t
.
// LNK2019g.cpp
// compile with: cl /EHsc /LD LNK2019g.cpp
#include "windows.h"
// WCHAR resolves to wchar_t
__declspec(dllexport) void func(WCHAR*) {}
Další ukázka používá knihovnu DLL v předchozí ukázce a vygeneruje LNK2019, protože typy unsigned short*
a WCHAR*
nejsou stejné.
// LNK2019h.cpp
// compile by using: cl /EHsc LNK2019h LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);
int main() {
func(0);
}
Chcete-li tuto chybu opravit, změňte unsigned short
nebo wchar_t
WCHAR
zkompilujte LNK2019g.cpp pomocí /Zc:wchar_t-
.
Viz také
Další informace o možných příčinách a řešeních pro LNK2019, LNK2001 a LNK1120 chyby najdete v otázce Stack Overflow: What is an undefined reference/unresolved external symbol error and how do I fix it?
.