Otrzymuję ten błąd, ale nie wiem, jak to naprawić.
Używam Visual Studio 2013. Nazwa rozwiązania została utworzona MyProjectTest Oto struktura mojego rozwiązania testowego:
- 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;
}
Jestem początkujący; jest to prosty program, który działa bez błędów. Czytałem w internecie i zainteresowałem się testem jednostkowym, więc stworzyłem projekt testowy:
Plik> Nowy> Projekt ...> Zainstalowano> Szablony> Visual C ++> Test> Projekt testu jednostkowego natywnego>
Nazwa: UnitTest1 Rozwiązanie: Dodaj do rozwiązania Następnie lokalizacja zostanie automatycznie przełączona na ścieżkę aktualnie otwartego rozwiązania Oto struktura folderów rozwiązania:
Edytowałem tylko plik 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
}
};
}
Ale pojawia się błąd LNK2019: nierozwiązany symbol zewnętrzny. Wiem, że brakuje implementacji funkcji wielokrotnej . Próbowałem usunąć plik function.cpp i zastąpiłem deklarację definicją i uruchomiłem. Jednak zapisywanie zarówno deklaracji, jak i definicji w tym samym pliku nie jest zalecane. Jak mogę naprawić ten błąd bez robienia tego? Czy powinienem zastąpić #include "../MyProjectTest/function.cpp"
w pliku unittest.cpp?
(Nie jestem zbyt dobry z angielskiego. Dzięki)
źródło
.LIB
rozszerzenie pliku. Aby skomplikować sprawy ... Biblioteki*.DLL
dołączane dynamicznie (tj. ) Mogą mieć towarzyszącą bibliotekę importu, która również ma.LIB
rozszerzenie pliku. Ta biblioteka importu zawiera listę wszystkich gadżetów dostarczanych przez*.DLL
. Aby uzyskać więcej informacji, przeczytaj: Przewodnik dla początkujących poOdpowiedzi:
Jedną z opcji byłoby to
function.cpp
w swoimUnitTest1
projekcie, ale to nie może być najbardziej struktura rozwiązanie idealne. Krótka odpowiedź na twój problem jest taka, że podczas budowaniaUnitTest1
projektu kompilator i konsolidator nie mają pojęcia, żefunction.cpp
istnieje, a także nie mają nic do połączenia, co zawiera definicjęmultiple
. Sposobem na rozwiązanie tego problemu jest użycie łączenia bibliotek.Ponieważ testy jednostkowe są w innym projekcie, zakładam, że Twoim zamiarem jest uczynienie tego projektu samodzielnym programem do testów jednostkowych. Dzięki funkcjom, które testujesz, znajdujących się w innym projekcie, możliwe jest zbudowanie tego projektu w bibliotece połączonej dynamicznie lub statycznie. Biblioteki statyczne są połączone z innymi programami w czasie kompilacji i mają rozszerzenie
.lib
, a biblioteki dynamiczne są połączone w czasie wykonywania i mają rozszerzenie.dll
. Dla mojej odpowiedzi wolę biblioteki statyczne.Możesz przekształcić swój pierwszy program w bibliotekę statyczną, zmieniając go we właściwościach projektu. Na karcie Ogólne powinna znajdować się opcja, w której projekt jest ustawiony na kompilację do pliku wykonywalnego (
.exe
). Możesz to zmienić na.lib
..lib
Plik będzie budować w tym samym miejscu co.exe
.W swoim
UnitTest1
projekcie możesz przejść do jego właściwości i na karcie Linker w kategorii Dodatkowe katalogi biblioteczne dodać ścieżkę do którejMyProjectTest
kompilacje. Następnie, dla dodatkowych zależności na karcie Konsolidator - dane wejściowe, najprawdopodobniej dodaj nazwę biblioteki statycznejMyProjectTest.lib
.To powinno pozwolić na zbudowanie projektu. Zauważ, że robiąc to,
MyProjectTest
nie będzie samodzielnym programem wykonywalnym, chyba że zmienisz jego właściwości kompilacji w razie potrzeby, co byłoby mniej niż idealne.źródło
W drzewie rozwiązań programu Visual Studio kliknij prawym przyciskiem myszy projekt „UnitTest1”, a następnie Dodaj -> Istniejący element -> wybierz plik ../MyProjectTest/function.cpp
źródło
Ponieważ chcę, aby mój projekt został skompilowany do samodzielnego EXE, połączyłem projekt UnitTest z plikiem function.obj wygenerowanym z pliku function.cpp i działa. Kliknij prawym przyciskiem myszy projekt „UnitTest1”> Właściwości konfiguracji> Konsolidator> Dane wejściowe> Dodatkowe zależności> dodaj „.. \ MyProjectTest \ Debug \ function.obj”
źródło
Właśnie natknąłem się na ten problem w Visual Studio 2013. Najwyraźniej posiadanie dwóch projektów w tym samym rozwiązaniu i ustawienie zależności to za mało. Musisz dodać odniesienie do projektu między nimi. Aby to zrobić:
źródło
okazało się, że używam plików .c z plikami .cpp. zmiana nazwy .c na .cpp rozwiązała mój problem.
źródło
Innym sposobem na uzyskanie tego błędu konsolidatora (tak jak ja) jest to, że eksportujesz wystąpienie klasy z biblioteki dll, ale nie zadeklarowałeś tej klasy jako importu / eksportu.
#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
Tak więc, mimo że głównie eksportowałem tylko wystąpienie klasy Book
book
, o którejBook
mowa powyżej, musiałem zadeklarować tę klasę jako klasę eksportu / importu, a w przeciwnym razie wywołaniebook.WordCount()
drugiej biblioteki dll powodowało błąd łącza.źródło
Przydarzyło mi się to, więc pomyślałem, że mogę podzielić się moim rozwiązaniem, tak proste, jak to było:
Sprawdź zestaw znaków obu projektów w Właściwości konfiguracyjne -> Ogólne -> Zestaw znaków
Mój projekt UnitTest używał domyślnego zestawu znaków Multi-Byte, podczas gdy moje biblioteki były w formacie Unicode .
Moja funkcja używała TCHAR jako parametru. W rezultacie w mojej bibliotece TCHAR został przekształcony w WCHAR, ale był to znak * w moim UnitTest: symbole były inne, ponieważ parametry w rzeczywistości nie były takie same.
źródło
Właśnie odkryłem, że
LNK2019
występuje to podczas kompilacji w programie Visual Studio 2015, jeśli zapomnisz podać definicję zadeklarowanej funkcji wewnątrz klasy.Błąd linkera był wysoce tajemniczy, ale zawęziłem to, czego brakowało, czytając błąd i podałem definicję poza klasą, aby to wyjaśnić.
źródło
w moim przypadku ustaw plik cpp na „kompilator C / C ++” we właściwości -> ogólne rozwiązanie błędu LNK2019.
źródło
Dla mnie działa, jeśli dodać w tej linii ryk
.vcxproj
witemGroup
pliku cpp, który jest podłączony do pliku nagłówka.<ClCompile Include="file.cpp" />
źródło
W programie Visual Studio 2017, jeśli chcesz przetestować członków publicznych, po prostu umieść swój prawdziwy projekt i projekt testowy w tym samym rozwiązaniu i dodaj odwołanie do swojego prawdziwego projektu w projekcie testowym.
Aby uzyskać więcej informacji, zobacz Testy jednostkowe języka C ++ w programie Visual Studio w blogu MSDN. Możesz również sprawdzić Napisz testy jednostkowe dla C / C ++ w programie Visual Studio, a także Użyj struktury testów jednostkowych firmy Microsoft dla języka C ++ w programie Visual Studio , to drugie dotyczy sytuacji, gdy chcesz przetestować niepubliczne elementy członkowskie i musisz umieścić testy w tym samym projekcie jako twój prawdziwy kod.
Pamiętaj, że rzeczy, które chcesz przetestować, będą musiały zostać wyeksportowane przy użyciu
__declspec(dllexport)
. Aby uzyskać więcej informacji, zobacz Eksportowanie z biblioteki DLL przy użyciu __declspec (dllexport) .źródło