Sdílet prostřednictvím


Chyba linkerů LNK2019

nevyřešený externsymbol "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 externchybu symbolu al.

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ázce 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, __fastcalla __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 zkompilovaný jako C vytváří ozdobené názvy symbolů, které se liší od zdobených názvů stejných symbolů deklarovaných 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í constmravenci propojení. Pokud chcete toto omezení obejít, můžete zahrnout const inicializace do souboru záhlaví a zahrnout ho do souborů .cpp, nebo můžete proměnnou nastavit jako neconst ant a použít constk němu odkaz na ant.

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 WinMainwWinMain 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 se chybová zpráva podobá nevyřešenému externsymbolu WinMain odkazovanému ve funkcifunction_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).

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 souborech .cpp 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 external function. Místo vygenerování vložené instrukce kompilátor vygeneruje volání external 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

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í. Jednotlivé exporty pro vložené funkce nejsou dostupné ve standardních knihovnách UCRT, které exportují jenom 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 symboly pro *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 externsymboly al. 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í.

  • Nástroje /EXPORTS a /SYMBOLS možnosti DUMPBIN vám můžou pomoct zjistit, které symboly jsou definovány v souborech .dll a objektu nebo knihovny. 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í nezakódovaný externsymbol al 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 externje deklarována al proměnná, 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_tWCHARzkompilujte 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?.