web-dev-qa-db-fra.com

Comment résoudre l'erreur LNK2019: fonction symbole externe non résolue?

Je reçois cette erreur, mais je ne sais pas comment la réparer.

J'utilise Visual Studio 2013. J'ai nommé la solution MyProjectTest Voici la structure de ma solution de test:

The structure

- function.h

#ifndef MY_FUNCTION_H
#define MY_FUNCTION_H

int multiple(int x, int y);
#endif

- function.cpp

#include "function.h"

int multiple(int x, int y){
    return x*y;
}

- main.cpp

#include <iostream>
#include <cstdlib>
#include "function.h"
using namespace std;

int main(){
    int a, b;
    cin >> a >> b;
    cout << multiple(a, b) << endl;

    system("pause");
    return 0;
}

Je suis un débutant; c'est un programme simple et il fonctionne sans erreur. J'ai lu sur Internet et je me suis intéressé au test unitaire. J'ai donc créé un projet de test:

Fichier> Nouveau> Projet ...> Installé> Modèles> Visual C++> Test> Projet de test d'unité native>

Nom: UnitTest1 Solution: Ajouter à la solution Ensuite, l'emplacement a été auto-commuté vers le chemin de la solution ouverte en cours. Voici la structure de dossiers de la solution:

Folder structure

J'ai seulement édité le fichier unittest1.cpp:

#include "stdafx.h"
#include "CppUnitTest.h"
#include "../MyProjectTest/function.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest1
{       
    TEST_CLASS(UnitTest1)
    {
    public:

        TEST_METHOD(TestEqual)
        {

            Assert::AreEqual(multiple(2, 3), 6);
            // TODO: Your test code here
        }

    };
}

Mais j'obtiens l'erreur LNK2019: symbole externe non résolu. Je sais que l'implémentation de la fonction multiple est manquante. J'ai essayé de supprimer le fichier function.cpp et j'ai remplacé la déclaration par la définition. Toutefois, l'écriture de la déclaration et de la définition dans le même fichier n'est pas recommandée. Comment puis-je réparer cette erreur sans le faire? Devrais-je remplacer par #include "../MyProjectTest/function.cpp" dans le fichier unittest.cpp? (Je ne suis pas très bon en anglais. Merci)

86
phibao37

Une option serait d'inclure function.cpp dans votre projet UnitTest1, mais il se peut que la structure de la solution ne soit pas idéale. La réponse courte à votre problème est que lors de la construction de votre projet UnitTest1, le compilateur et l'éditeur de liens n'ont aucune idée de l'existence de function.cpp et n'ont rien à lier qui contienne une définition de multiple. Une façon de résoudre ce problème consiste à utiliser des bibliothèques de liens.

Étant donné que vos tests unitaires sont dans un projet différent, je suppose que votre intention est de faire de ce projet un programme de test unitaire autonome. Les fonctions que vous testez étant situées dans un autre projet, il est possible de construire ce projet dans une bibliothèque liée de manière dynamique ou statique. Les bibliothèques statiques sont liées à d'autres programmes au moment de la construction et portent l'extension .lib, tandis que les bibliothèques dynamiques sont liées à l'exécution et portent l'extension .dll. Pour ma réponse, je préférerai les bibliothèques statiques.

Vous pouvez transformer votre premier programme en une bibliothèque statique en le modifiant dans les propriétés du projet. Il devrait y avoir une option sous l'onglet Général où le projet est configuré pour construire un exécutable (.exe). Vous pouvez changer ceci en .lib. Le fichier .lib sera créé au même endroit que le .exe.

Dans votre projet UnitTest1, vous pouvez accéder à ses propriétés et, sous l'onglet Éditeur de liens de la catégorie Répertoires de bibliothèque supplémentaires, ajoutez le chemin d'accès à lequel MyProjectTest est généré. Ensuite, pour les dépendances supplémentaires sous l’éditeur de liens - onglet Entrée, ajoutez le nom de votre bibliothèque statique, probablement MyProjectTest.lib.

Cela devrait permettre à votre projet de se construire. Notez qu'en faisant cela, MyProjectTest ne sera pas un programme exécutable autonome à moins que vous ne modifiiez ses propriétés de construction selon vos besoins, ce qui serait moins qu'idéal.

66
kevintodisco

Dans l'arborescence de la solution Visual Studio, cliquez avec le bouton droit de la souris sur le projet 'UnitTest1', puis sur Ajouter -> Article existant -> choisissez le fichier ../MyProjectTest/function.cpp.

35
Niyaz Ivanov

Puisque je veux que mon projet soit compilé dans un fichier EXE autonome, j'ai lié le projet UnitTest au fichier function.obj généré à partir de function.cpp et cela fonctionne. Cliquez avec le bouton droit sur le projet 'UnitTest1'> Propriétés de configuration> Éditeur de liens> Entrée> Dépendances supplémentaires> ajoutez "..\MonProjetTest\Debug\function.obj".

14
harrygg

Je viens de rencontrer ce problème dans Visual Studio 2013. Apparemment, avoir deux projets dans la même solution et définir les dépendances ne suffit pas. Vous devez ajouter une référence de projet entre eux. Pour faire ça:

  1. Faites un clic droit sur le projet dans la solution explorer
  2. Cliquez sur Ajouter => Références ...
  3. Cliquez sur le bouton Ajouter une nouvelle référence
  4. Cochez les cases pour les projets sur lesquels ce projet repose
  5. Cliquez sur OK
8
Kevin Dill

il s'est avéré que j'utilisais des fichiers .c avec des fichiers .cpp. renommer .c en .cpp a résolu mon problème.

8
cahit beyaz

Si vous exportez une instance d'une classe à partir d'une dll sans avoir déclaré cette classe elle-même en tant qu'import/export, vous pouvez également obtenir cette erreur (comme j'étais).

 #ifdef  MYDLL_EXPORTS 
    #define DLLEXPORT __declspec(dllexport)  
 #else
    #define DLLEXPORT __declspec(dllimport)  
 #endif

class DLLEXPORT Book // <--- this class must also be declared as export/import
{
public: 
    Book();
    ~Book();
    int WordCount();
};

DLLEXPORT extern Book book; // <-- This is what I really wanted, to export book object

Donc, même si au départ j'exportais simplement une instance de la classe Book appelée book ci-dessus, je devais déclarer la classe Book en tant que classe d'exportation/importation, sinon l'appelant book.WordCount() dans l'autre DLL provoquait une erreur de liaison.

6
zar

Je viens de découvrir que LNK2019 se produit lors de la compilation dans Visual Studio 2015 si vous oubliez de fournir la définition d'une fonction déclarée dans une classe.

L'erreur de l'éditeur de liens était hautement cryptique, mais j'ai réduit ce qui manquait en lisant l'erreur et en fournissant la définition en dehors de la classe pour la clarifier.

1
Mushy

C'est ce qui m'est arrivé alors j'ai pensé partager ma solution, aussi simple soit-elle:

Vérifiez le jeu de caractères des deux projets dans Propriétés de configuration -> Général -> Jeu de caractères

Mon projet UnitTest utilisait le jeu de caractères par défaut Multi-Byte, tandis que mes bibliothèques étaient dans nicode.
Ma fonction utilisait un paramètre TCHAR. En conséquence, dans ma bibliothèque, ma TCHAR était transformée en un WCHAR mais c'était un char * sur mon UnitTest: le symbole était différent parce que les paramètres n'étaient pas vraiment les mêmes à la fin.

1
Enyx

Pour moi, si j’ajoute cette ligne ci-dessous dans le fichier .vcxproj du fichier itemGroup cpp, qui est connecté au fichier d’en-tête.

<ClCompile Include="file.cpp" />
0
Nejc Galof

Dans Visual Studio 2017, si vous souhaitez tester des membres publics, placez simplement votre projet réel et votre projet test dans la même solution, puis ajoutez une référence à votre projet réel dans le projet test.

Voir Test des unités C++ dans Visual Studio sur le blog MSDN pour plus de détails. Vous pouvez également vérifier écrire des tests unitaires pour C/C++ dans Visual Studio ainsi que tiliser le framework de test unitaire Microsoft pour C++ dans Visual Studio , ce dernier étant le cas échéant. testez les membres non publics et devez placer les tests dans le même projet que votre code réel.

Notez que les éléments que vous souhaitez tester devront être exportés avec __declspec(dllexport). Voir Exportation à partir d'un DLL à l'aide de __declspec (dllexport) pour plus de détails.

0
user276648