Partager via


Erreur des outils Éditeur de liens LNK2005

symbole déjà défini dans l’objet

Le symbole de symbole a été défini plusieurs fois.

Cette erreur est suivie d’une erreur irrécupérable LNK1169.

Causes possibles et solutions

En règle générale, cette erreur signifie que vous avez rompu la règle de définition unique, qui autorise une seule définition pour un modèle, une fonction, un type ou un objet utilisé dans un fichier objet donné, et une seule définition dans l’exécutable entier pour les objets ou fonctions visibles en externe.

Voici quelques causes courantes de cette erreur.

  • Cette erreur peut se produire lorsqu’un fichier d’en-tête définit une variable. Par exemple, si vous incluez ce fichier d’en-tête dans plusieurs fichiers sources dans votre projet, une erreur se produit :

    // LNK2005_global.h
    int global_int;  // LNK2005
    

    Voici les solutions possibles :

    • Déclarez la variable extern dans le fichier d’en-tête : extern int global_int;puis définissez-la et initialisez-la éventuellement dans un seul et seul fichier source : int global_int = 17;. Cette variable est désormais une variable globale que vous pouvez utiliser dans n’importe quel fichier source en la externdéclarant, par exemple, en incluant le fichier d’en-tête. Nous recommandons cette solution pour les variables qui doivent être globales, mais une bonne pratique d’ingénierie logicielle réduit les variables globales.

    • Déclarez la variable statique : static int static_int = 17;. Cela limite l’étendue de la définition au fichier objet actuel et permet à plusieurs fichiers d’objets d’avoir leur propre copie de la variable. Nous vous déconseillons de définir des variables statiques dans les fichiers d’en-tête en raison du risque de confusion avec les variables globales. Préférez déplacer des définitions de variables statiques dans les fichiers sources qui les utilisent.

    • Déclarez la variable selectany : __declspec(selectany) int global_int = 17;. Cela indique à l’éditeur de liens de choisir une définition à utiliser par toutes les références externes et d’ignorer le reste. Cette solution est parfois utile lors de la combinaison de bibliothèques d’importation. Sinon, nous ne le recommandons pas comme moyen d’éviter les erreurs de l’éditeur de liens.

  • Cette erreur peut se produire lorsqu’un fichier d’en-tête définit une fonction qui n’est pas inline. Si vous incluez ce fichier d’en-tête dans plusieurs fichiers sources, vous obtenez plusieurs définitions de la fonction dans l’exécutable.

    // LNK2005_func.h
    int sample_function(int k) { return 42 * (k % 167); }  // LNK2005
    

    Voici les solutions possibles :

    • Ajoutez le inline mot clé à la fonction :

      // LNK2005_func_inline.h
      inline int sample_function(int k) { return 42 * (k % 167); }
      
    • Supprimez le corps de la fonction du fichier d’en-tête et laissez uniquement la déclaration, puis implémentez la fonction dans un seul et un seul fichier source :

      // LNK2005_func_decl.h
      int sample_function(int);
      
      // LNK2005_func_impl.cpp
      int sample_function(int k) { return 42 * (k % 167); }
      
  • Cette erreur peut également se produire si vous définissez des fonctions membres en dehors de la déclaration de classe dans un fichier d’en-tête :

    // LNK2005_member_outside.h
    class Sample {
    public:
        int sample_function(int);
    };
    int Sample::sample_function(int k) { return 42 * (k % 167); }  // LNK2005
    

    Pour résoudre ce problème, déplacez les définitions de fonction membre à l’intérieur de la classe. Les fonctions membres définies à l’intérieur d’une déclaration de classe sont implicitement inline.

    // LNK2005_member_inline.h
    class Sample {
    public:
        int sample_function(int k) { return 42 * (k % 167); }
    };
    
  • Cette erreur peut se produire si vous liez plusieurs versions de la bibliothèque standard ou crT. Par exemple, si vous tentez de lier les bibliothèques CRT de vente au détail et de débogage, ou les versions statiques et dynamiques d’une bibliothèque, ou deux versions différentes d’une bibliothèque standard à votre exécutable, cette erreur peut être signalée plusieurs fois. Pour résoudre ce problème, supprimez toute une copie de chaque bibliothèque de la commande de lien. Nous vous déconseillons de combiner les bibliothèques de vente au détail et de débogage, ou différentes versions d’une bibliothèque, dans le même exécutable.

    Pour indiquer à l’éditeur de liens d’utiliser des bibliothèques autres que les valeurs par défaut, sur la ligne de commande, spécifiez les bibliothèques à utiliser et utilisez l’option /NODEFAULTLIB pour désactiver les bibliothèques par défaut. Dans l’IDE, ajoutez des références à votre projet pour spécifier les bibliothèques à utiliser, puis ouvrez la boîte de dialogue Pages de propriétés de votre projet, puis, dans l’éditeur de liens, la page de propriétés d’entrée, définissez Ignorer toutes les bibliothèques par défaut ou ignorez les propriétés de bibliothèques par défaut spécifiques pour désactiver les bibliothèques par défaut.

  • Cette erreur peut se produire si vous combinez l’utilisation de bibliothèques statiques et dynamiques lorsque vous utilisez l’option /clr . Par exemple, cette erreur peut se produire si vous générez une DLL à utiliser dans votre exécutable qui lie le CRT statique. Pour résoudre ce problème, utilisez uniquement des bibliothèques statiques ou uniquement des bibliothèques dynamiques pour l’intégralité de l’exécutable et pour toutes les bibliothèques que vous générez à utiliser dans l’exécutable.

  • Cette erreur peut se produire si le symbole est une fonction empaquetée (créée par la compilation avec /Gy) et qu’elle a été incluse dans plusieurs fichiers, mais a été modifiée entre les compilations. Pour résoudre ce problème, recompilez tous les fichiers qui incluent la fonction empaquetée.

  • Cette erreur peut se produire si le symbole est défini différemment dans deux objets membres dans différentes bibliothèques, et les deux objets membres sont utilisés. Une façon de résoudre ce problème lorsque les bibliothèques sont liées statiquement consiste à utiliser l’objet membre d’une seule bibliothèque et à inclure cette bibliothèque en premier sur la ligne de commande de l’éditeur de liens. Pour utiliser les deux symboles, vous devez créer un moyen de les distinguer. Par exemple, si vous pouvez générer les bibliothèques à partir de la source, vous pouvez encapsuler chaque bibliothèque dans un espace de noms unique. Vous pouvez également créer une bibliothèque wrapper qui utilise des noms uniques pour encapsuler des références à l’une des bibliothèques d’origine, lier la nouvelle bibliothèque à la bibliothèque d’origine, puis lier l’exécutable à votre nouvelle bibliothèque au lieu de la bibliothèque d’origine.

  • Cette erreur peut se produire si une extern const variable est définie deux fois et a une valeur différente dans chaque définition. Pour résoudre ce problème, définissez la constante une seule fois, ou utilisez des espaces de noms ou enum class des définitions pour distinguer les constantes.

  • Cette erreur peut se produire si vous utilisez uuid.lib en combinaison avec d’autres fichiers .lib qui définissent des GUID (par exemple, oledb.lib et adsiid.lib). Par exemple :

    oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject
    already defined in uuid.lib(go7.obj)
    

    Pour résoudre ce problème, ajoutez /FORCE :MULTIPLE aux options de ligne de commande de l’éditeur de liens et assurez-vous que uuid.lib est la première bibliothèque référencée.