Partager via


Erreur des outils Éditeur de liens LNK2019

Mise à jour : novembre 2007

Message d'erreur

symbole externe non résolu 'symbole' référencé dans la fonction 'fonction'
unresolved external symbol 'symbol' referenced in function 'function'

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

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

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

L'erreur LNK2019 peut également se produire lorsque vous déclarez des données membres static sans les définir. 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 un des fichiers inclus dans la génération, l'éditeur de liens générera LNK2019. Ces définitions peuvent être ajoutées par inclusion du fichier de code source contenant les définitions dans la compilation. Vous pouvez aussi passer à l'éditeur de liens des fichiers .obj ou .lib contenant les définitions.

Si, pour les projets C++ issus des versions précédentes et mis à niveau dans la version actuelle, __UNICODE était défini et que 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 LNK2019 sont notamment :

  • La déclaration du symbole contient une faute d'orthographe, donc le symbole n'a pas le même nom que sa définition.

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

  • 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". Dans ce cas, modifiez la déclaration, par exemple au lieu de :

    extern int i;
    extern void g();
    

    utilisez :

    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 ci-dessous devrait ê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 permettra de voir à quel fichier l'éditeur de liens fait référence. Les options /EXPORTS et /SYMBOLS de l'utilitaire DUMPBIN permettent aussi de voir quels symboles sont définis dans vos fichiers dll et objet/bibliothèque.

La Base de connaissances Microsoft contient davantage d'informations à propos de l'erreur LNK2019 ; consultez https://www.microsoft.com/france/support.

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 plus d'informations, consultez Récapitulatif des modifications sans rupture au moment de la compilation.

Pour produire un code valide dans les versions Visual Studio .NET 2003 et Visual Studio .NET 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 ; /Zc:wchar_t est désormais activé par défaut. Tous les modules n'ont pas pu être compilés avec les mêmes paramètres /Zc:wchar_t ; par conséquent, les références de type ne sont pas résolues en types compatibles. Pour remédier à cela, vérifiez que les types contenus dans tous les modules sont compatibles, soit en compilant avec les paramètres /Zc:wchar_t appropriés (par exemple, en utilisant /Zc:wchar_t- lors de la génération de modules avec l'ensemble d'outils Visual C++ 2005 qui seront liés à des modules de versions antérieures), soit en mettant à jour vos types afin qu'ils soient compatibles, dans la mesure du possible.

Les références explicites à comsupp.lib (à partir du pragma comment ou via la ligne de commande) doivent être modifiées pour utiliser à présent comsuppw.lib ou comsuppwd.lib, car /Zc:wchar_t est maintenant activé par défaut. comsupp.lib doit toujours être utilisé lors de la compilation avec /Zc:wchar_t-.

Pour plus d'informations, consultez Modifications avec rupture dans le compilateur Visual C++ 2005 et /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 remédier à cette erreur, remplacez unsigned short par wchar_t ou WCHAR, ou compilez LNK2019g.cpp avec /Zc:wchar_t-.

L'erreur LNK2019 peut également se produire si vous générez une application console avec /SUBSYSTEM:WINDOWS. Le symbole non résolu sera _WinMain@16. Dans ce cas, effectuez simplement la liaison avec /SUBSYSTEM:CONSOLE.