Share via


Erreur des outils Éditeur de liens LNK2019

externnon résolu al symbol 'symbol' référencé dans la fonction 'function'

Le code compilé pour la fonction effectue une référence ou un appel au symbole, mais l’éditeur de liens ne trouve pas la définition de symbole dans les bibliothèques ou les fichiers objet.

Ce message d’erreur est suivi d’une erreur irrécupérable LNK1120. Pour corriger les LNK1120 d’erreurs, vous devez d’abord corriger toutes les erreurs LNK2001 et LNK2019.

Causes possibles

Il existe de nombreuses façons d’obtenir cette erreur. Toutes impliquent une référence à une fonction ou à une variable pour laquelle l’éditeur de liens n’a pas pu résoudre ou trouver une définition. Le compilateur peut identifier lorsqu’un symbole n’est pas déclaré, mais il ne peut pas indiquer quand le symbole n’est pas défini. Cela est dû au fait que la définition peut se trouver dans un autre fichier ou bibliothèque source. Si un symbole est référencé mais jamais défini, l’éditeur de liens génère une erreur de symbole al non résolu extern.

Voici un aperçu des problèmes courants qui provoquent l'erreur LNK2019 :

Le fichier source qui contient la définition du symbole n’est pas compilé

Dans Visual Studio, vérifiez que le fichier source qui définit le symbole est compilé dans le cadre de votre projet. Vérifiez le répertoire de sortie de build intermédiaire pour un fichier .obj correspondant. Si le fichier source n’est pas compilé, cliquez avec le bouton droit sur le fichier dans Explorateur de solutions, puis choisissez Propriétés pour case activée les propriétés du fichier. La page Général des propriétés>de configuration doit afficher un type d’élément du compilateur C/C++. Sur la ligne de commande, vérifiez que le fichier source qui contient la définition est compilé.

Le fichier objet ou la bibliothèque qui contient la définition du symbole n’est pas lié

Dans Visual Studio, vérifiez que le fichier objet ou la bibliothèque qui contient la définition de symbole est lié dans le cadre de votre projet. Sur la ligne de commande, vérifiez que la liste des fichiers à lier inclut le fichier objet ou la bibliothèque.

La déclaration du symbole n’est pas orthographiée de la même façon que la définition du symbole

Vérifiez que vous utilisez l’orthographe et la mise en majuscules correctes dans la déclaration et la définition, et où que le symbole soit utilisé ou appelé.

Une fonction est utilisée, mais le type ou le nombre des paramètres ne correspondent pas à la définition de fonction

La déclaration de la fonction doit correspondre à la définition. Vérifiez que l’appel de fonction correspond à la déclaration et que la déclaration correspond à la définition. Le code qui appelle des modèles de fonction doit également avoir des déclarations de modèle de fonction correspondantes qui incluent les mêmes paramètres de modèle que la définition. Pour obtenir un exemple d’incompatibilité de déclaration de modèle, consultez l’exemple LNK2019e.cpp dans la section Exemples.

Une fonction ou une variable est déclarée, mais non définie

LNK2019 peut se produire lorsqu’une déclaration existe dans un fichier d’en-tête, mais qu’aucune définition correspondante n’est implémentée. Pour les fonctions membres ou static les membres de données, l’implémentation doit inclure le sélecteur d’étendue de classe. Pour obtenir un exemple, consultez Missing Function Body or Variable.

La convention d’appel est différente entre la déclaration de fonction et la définition de la fonction

Certaines conventions d’appel (__cdecl, __stdcall, __fastcallet __vectorcall) sont encodées dans le cadre du nom décoré. Vérifiez que la convention d’appel est identique.

Un symbole est défini dans un fichier C, mais déclaré sans utiliser extern "C" dans un fichier C++

Un fichier compilé en C crée des noms décorés pour les symboles qui sont différents des noms décorés pour les mêmes symboles déclarés dans un fichier C++, sauf si vous utilisez un extern "C" modificateur. Vérifiez que la déclaration correspond à la liaison de compilation pour chaque symbole. De même, si vous définissez un symbole dans un fichier C++ qui sera utilisé par un programme C, utilisez extern "C" dans la définition.

Un symbole est défini comme static puis référencé ultérieurement en dehors du fichier

En C++, contrairement à C, les fourmis globales constont static une liaison. Pour contourner cette limitation, vous pouvez inclure les const initialisations dans un fichier d’en-tête et inclure cet en-tête dans vos fichiers .cpp, ou vous pouvez rendre la variable non-antconst et utiliser une constréférence dent pour y accéder.

Un static membre d’une classe n’est pas défini

Un static membre de classe doit avoir une définition unique, ou il enfreint la règle de définition unique. Un static membre de classe qui ne peut pas être défini inline doit être défini dans un fichier source à l’aide de son nom complet. S’il n’est pas défini du tout, l’éditeur de liens génère LNK2019.

Une dépendance de build est définie uniquement en tant que dépendance de projet dans la solution

Dans les versions antérieures de Visual Studio, ce niveau de dépendance était suffisant. Toutefois, à partir de Visual Studio 2010, Visual Studio nécessite une référence de projet à projet. Si votre projet n’a pas de référence de projet à projet, vous pouvez recevoir cette erreur de l’éditeur de liens. Ajoutez une référence entre projets pour corriger ce problème.

Un point d’entrée n’est pas défini

Le code de l’application doit définir un point d’entrée approprié : main ou wmain pour les applications console, ainsi que WinMainwWinMain pour les applications Windows. Pour plus d’informations, consultez main les arguments de fonction et de ligne de commande ou WinMain la fonction. Pour utiliser un point d’entrée personnalisé, spécifiez l’option /ENTRY d’éditeur de liens (symbole de point d’entrée).

Vous générez une application console à l’aide des paramètres d’une application Windows

Si le message d’erreur est similaire au symbole al non résolu externréférencé dans la fonctionfunction_name, liez à l’aide /SUBSYSTEM:CONSOLE au lieu de /SUBSYSTEM:WINDOWSWinMain . Pour plus d’informations sur ce paramètre et pour obtenir des instructions sur la définition de cette propriété dans Visual Studio, consultez /SUBSYSTEM (Spécifier le sous-système).

Les bibliothèques et les fichiers objet liés à votre code doivent être compilés pour la même architecture que votre code. Vérifiez que les bibliothèques que vos références de projet sont compilées pour la même architecture que votre projet. Vérifiez que la /LIBPATHpropriété Répertoires de bibliothèques supplémentaires pointe vers des bibliothèques conçues pour l’architecture appropriée.

Vous utilisez différentes options de compilateur pour l’incorporation de fonctions dans différents fichiers sources

L’utilisation de fonctions inline définies dans des fichiers .cpp et le panachage d’options de compilateur pour incorporer des fonctions inline dans différents fichiers sources peut occasionner l’erreur LNK2019. Pour plus d'informations, consultez Function Inlining Problems.

Vous utilisez des variables automatiques en dehors de leur étendue

Les variables automatiques (portée de fonction) ne peuvent être utilisées que dans la portée de la fonction en question. Ces variables ne peuvent pas être déclarées comme étant extern et utilisées dans d’autres fichiers sources. Pour obtenir un exemple, consultez Automatic (Function Scope) Variables.

Vous appelez des fonctions intrinsèques ou transmettez des types d’arguments à des fonctions intrinsèques qui ne sont pas prises en charge sur votre architecture cible

Par exemple, si vous utilisez une AVX2 intrinsèque, mais que vous ne spécifiez pas l’option /ARCH:AVX2 du compilateur, le compilateur suppose que l’intrinsèque est une externfonction al. Au lieu de générer une instruction inline, le compilateur génère un appel à un externsymbole al portant le même nom que l’intrinsèque. Quand l'éditeur de liens tente de trouver la définition de cette fonction manquante, il génère l'erreur LNK2019. Veillez à utiliser uniquement les intrinsèques et les types pris en charge par votre architecture cible.

Vous mélangez du code qui utilise natif wchar_t avec du code qui ne le fait pas

Le travail de conformité du langage C++ effectué dans Visual Studio 2005 a fait wchar_t par défaut un type natif. Si tous les fichiers n’ont pas été compilés à l’aide des mêmes /Zc:wchar_t paramètres, les références de type peuvent ne pas être résolues en types compatibles. Vérifiez que wchar_t les types dans tous les fichiers bibliothèque et objet sont compatibles. Effectuez une mise à jour à partir d’un wchar_t typedef ou utilisez des paramètres /Zcwchar_t cohérents lorsque vous compilez.

Une static bibliothèque créée à l’aide d’une version de Visual Studio avant que Visual Studio 2015 puisse entraîner des erreurs LNK2019 lorsqu’elles sont liées à l’UCRT. Les fichiers d’en-tête <stdio.h>UCRT, <conio.h>et <wchar.h>définissent maintenant de nombreuses *printf* et *scanf* variantes en tant que inline fonctions. Les fonctions insérées sont implémentées par un plus petit ensemble de fonctions courantes. Les exportations individuelles pour les fonctions inline ne sont pas disponibles dans les bibliothèques UCRT standard, qui exportent uniquement les fonctions courantes. Il existe deux façons de résoudre ce problème. La méthode que nous vous recommandons est de reconstruire la bibliothèque héritée avec votre version actuelle de Visual Studio. Assurez-vous que le code de la bibliothèque utilise les en-têtes standard pour les définitions des fonctions et *scanf* les *printf* définitions qui ont provoqué les erreurs. Une autre option pour une bibliothèque héritée que vous ne pouvez pas reconstruire consiste à ajouter legacy_stdio_definitions.lib à la liste des bibliothèques que vous liez. Ce fichier de bibliothèque fournit des symboles pour les *printf**scanf* fonctions incluses dans les en-têtes UCRT. Pour plus d’informations, consultez la section Bibliothèques dans Vue d’ensemble des problèmes de mise à niveau potentiels.

Problèmes de bibliothèque tiers et vcpkg

Si vous voyez cette erreur lorsque vous essayez de configurer une bibliothèque tierce dans le cadre de votre build, envisagez d’utiliser vcpkg. vcpkg est un gestionnaire de package C++ qui utilise vos outils Visual Studio existants pour installer et générer la bibliothèque. vcpkg prend en charge une liste importante et croissante de bibliothèques tierces. Elle définit toutes les propriétés et dépendances de configuration requises pour les builds réussies dans le cadre de votre projet.

Outils de diagnostic

Parfois, il est difficile de dire pourquoi l’éditeur de liens ne peut pas trouver une définition de symbole particulière. Souvent, le problème est que vous n’avez pas inclus le code qui contient la définition dans votre build. Ou bien, les options de génération ont créé différents noms décorés pour externles symboles al. Il existe plusieurs outils et options qui peuvent vous aider à diagnostiquer les erreurs LNK2019.

  • L’option /VERBOSE éditeur de liens peut vous aider à déterminer les fichiers auxquels l’éditeur de liens fait référence. Cette option peut vous aider à vérifier si le fichier qui contient la définition du symbole est inclus dans votre build.

  • Les /EXPORTS options de /SYMBOLS l’utilitaire DUMPBIN peuvent vous aider à découvrir quels symboles sont définis dans vos fichiers .dll et objet ou bibliothèque. Assurez-vous que les noms décorés exportés correspondent aux noms décorés que l’éditeur de liens recherche.

  • L’utilitaire UNDNAME peut vous montrer le symbole al non externdécoré équivalent pour un nom décoré.

Exemples

Voici plusieurs exemples de code qui provoquent des erreurs LNK2019, ainsi que des informations sur la façon de corriger les erreurs.

Un symbole est déclaré mais pas défini

Dans cet exemple, une externvariable al est déclarée, mais non définie :

// 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
}

Voici un autre exemple où une variable et une fonction sont déclarées comme extern étant, mais aucune définition n’est fournie :

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

À moins i d’être g défini dans l’un des fichiers inclus dans la build, l’éditeur de liens génère LNK2019. Vous pouvez corriger les erreurs en incluant le fichier de code source qui contient les définitions dans le cadre de la compilation. Vous pouvez également transmettre des .obj fichiers ou .lib des fichiers qui contiennent les définitions à l’éditeur de liens.

Un static membre de données est déclaré mais non défini

LNK2019 peut également se produire lorsqu’un static membre de données est déclaré, mais non défini. L'exemple suivant génère l'erreur LNK2019 et montre comment la corriger.

// 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;
}

Les paramètres de déclaration ne correspondent pas à la définition

Le code qui appelle des modèles de fonction doit avoir des déclarations de modèle de fonction correspondantes. Les déclarations doivent inclure les mêmes paramètres de modèle que la définition. L'exemple suivant génère l'erreur LNK2019 sur un opérateur défini par l'utilisateur et montre comment la corriger.

// 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
}

Définitions de type incohérentes wchar_t

Cet exemple crée une DLL qui a une exportation qui utilise WCHAR, qui se résout en 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’exemple suivant utilise la DLL dans l’exemple précédent et génère LNK2019, car les types unsigned short* et WCHAR* ne sont pas les mêmes.

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

int main() {
   func(0);
}

Pour corriger cette erreur, modifiez unsigned shortwchar_t ou WCHARcompilez LNK2019g.cpp à l’aide /Zc:wchar_t-de .

Voir aussi

Pour plus d’informations sur les causes et solutions possibles pour LNK2019, LNK2001 et LNK1120 erreurs, consultez la question Stack Overflow : What is an undefined reference/unresolved external symbol error and how do I fix it?.