Partager via


Erreur des outils Éditeur de liens LNK2019

symbole externe non résolu 'symbole' référencé dans la fonction 'fonction'

Un symbole externe non défini (symbol) a été trouvé dans function. Pour résoudre cette erreur, fournissez une définition de symbol ou supprimez le code qui y fait référence. Pour plus d'informations, consultez les documents suivants :

L'exemple suivant génère l'erreur LNK2019.

// LNK2019.cpp
// LNK2019 expected
extern char B[100];   // B is not available to the linker
int main() {
   B[0] = ' ';
}

L'erreur LNK2019 peut également se produire lorsqu'un membre de données statique est déclaré mais pas défini. L'exemple suivant génère l'erreur LNK2019.

// LNK2019b.cpp
// LNK2019 expected
struct C {
   static int s;
};

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

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

Prenons l'exemple suivant.

// LNK2019c.cpp
// LNK2019 expected
extern int i;
extern void g();
void f() {
   i++;
   g();
}
int main() {}

Si i et g ne sont pas définis dans l'un des fichiers de la build, l'éditeur de liens génère l'erreur LNK2019. Vous pouvez ajouter ces définitions en incluant dans la compilation le fichier de code source qui contient les définitions. Vous pouvez aussi passer à l'éditeur de liens les fichiers .obj ou .lib qui contiennent les définitions.

Si, pour les projets C++ créés dans des versions antérieures et mis à niveau vers la version actuelle, __UNICODE était défini et si le point d'entrée était WinMain, vous devez changer le nom de la fonction du point d'entrée en _tWinMain ou wWinMain.

Les problèmes courants à l'origine de l'erreur LNK2019 sont notamment :

  • La déclaration du symbole n'a pas la même orthographe que la définition du symbole.

  • Une fonction utilisée comporte un nombre ou un type de paramètres qui ne correspond pas à la définition de la fonction.

  • La dépendance de génération n'est définie qu'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, depuis Visual Studio 2010, Visual Studio requiert une référence entre projets. Si votre projet n'a pas de référence entre projets, vous pouvez recevoir cette erreur de l'éditeur de liens.

  • La convention d'appel (__cdecl, __stdcall ou __fastcall) est différente entre l'utilisation d'une déclaration de fonction et la définition de fonction.

  • Les définitions de symboles sont dans un fichier qui a été compilé comme programme C, alors que les symboles sont déclarés dans un fichier C++ sans un modificateur extern "C". Si tel est le cas, modifiez la déclaration. Par exemple, au lieu de

    extern int i;
    extern void g();
    

    use

    extern "C" int i;
    extern "C" void g();
    

    De même, si vous définissez un symbole dans un fichier C++ à utiliser par un programme C, utilisez extern "C" dans la définition.

  • Un symbole est défini comme static puis référencé en dehors du fichier. En C++, contrairement à C, les constantes globales ont une liaison static. Pour éviter cette limitation, vous pouvez inclure les initialisations de const dans un fichier d'en-tête et inclure cet en-tête dans votre fichier .cpp ou rendre la variable non constante et utiliser une référence à une constante pour y accéder.

  • Un membre statique d'une classe n'est pas défini. Par exemple, la variable membre si dans la déclaration de classe de l'exemple suivant doit être définie séparément.

    // LNK2019d.cpp
    #include <stdio.h>
    struct X {
       static int si;
    };
    
    // int X::si = 0;   // uncomment this line to resolve
    
    int main() {
       X *px = new X[2];
       printf_s("\n%d",px[0].si);   // LNK2019
    }
    

L'exemple suivant génère l'erreur LNK2019 sur un opérateur défini par l'utilisateur.

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

template<class T> class 
Test {
   friend ostream& operator<<(ostream&, Test&);
   // Uncomment the following line to resolve.
   // 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;   // unresolved external
}

L'option d'éditeur de liens /VERBOSE vous permet d'identifier les fichiers auxquels l'éditeur de liens fait référence. Les options /EXPORTS et /SYMBOLS de l'utilitaire DUMPBIN vous permettent aussi de découvrir les symboles définis dans vos fichiers dll et vos fichiers objets/bibliothèques.

Pour plus d'informations à propos de LNK2019, consultez le site Web Support Microsoft.

L'erreur LNK2019 peut également être due à la mise en conformité du compilateur pour Visual Studio .NET 2003 : friends et spécialisation de modèle. Dans Visual Studio .NET 2003, la déclaration d'une fonction friend portant le même nom qu'un modèle de fonction ne fait pas référence à ce modèle de fonction à moins que les arguments template soient spécifiés explicitement dans la déclaration friend.

Si vous ne spécifiez pas d'argument template, la déclaration friend déclare une fonction sans modèle.

Pour produire un code valide dans les versions Visual Studio .NET 2003 et Visual Studio .NET 2002 de Visual C++, spécifiez explicitement la liste d'arguments template de la fonction friend.

// LNK2019f.cpp
// LNK2019 expected
template<class T>
void f(T) {}

template<class T>
struct S {
   friend void f(T);
   // try the folowing line instead
   // friend void f<T>(T);
};

int main() {
   S<int> s;
   f(1);   // unresolved external
}

L'erreur LNK2019 peut également être due à la mise en conformité réalisée dans Visual C++ 2005 ; en d'autres termes, /Zc:wchar_t est désormais activé par défaut. Il est possible que les modules n'aient pas tous pu être compilés à l'aide des mêmes paramètres /Zc:wchar_t ; par conséquent, les références de type ne sont peut-être pas résolues en types compatibles. Assurez-vous que les types contenus dans tous les modules sont compatibles, soit en compilant à l'aide des paramètres /Zc:wchar_t appropriés (par exemple, utilisez /Zc:wchar_t- lors de la génération de modules avec les outils Visual C++ qui doivent être liés à des modules de versions antérieures), soit en mettant à jour les types afin qu'ils soient compatibles, dans la mesure du possible.

Remplacez les références explicites à comsupp.lib (à partir du pragma comment ou sur la ligne de commande) par comsuppw.lib ou comsuppwd.lib, car /Zc:wchar_t est désormais activé par défaut. Continuez à utiliser comsupp.lib lorsque vous compilez à l'aide de /Zc:wchar_t-.

Pour plus d'informations, consultez /Zc:wchar_t (wchar_t est un type natif).

L'exemple suivant crée une exportation utilisant WCHAR qui est résolue en wchar_t.

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

L'exemple suivant génère l'erreur LNK2019.

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

int main() {
   func(0);
}

Pour résoudre cette erreur, remplacez unsigned short par wchar_t ou par WCHAR, ou compilez LNK2019g.cpp à l'aide de /Zc:wchar_t-.

Vous pouvez également recevoir l'erreur LNK2019 si vous générez une application console à l'aide de /SUBSYSTEM:WINDOWS. Le symbole non résolu sera _WinMain@16. Dans ce cas, effectuez simplement la liaison à l'aide de /SUBSYSTEM:CONSOLE.