Подтвердить что ты не робот

Как решить ошибку LNK2019: нерешенный внешний символ - функция?

Я получаю эту ошибку, но я не знаю, как ее исправить.

Я использую Visual Studio 2013. Я сделал имя решения MyProjectTest Это структура моего тестового решения:

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;
}

Я новичок; это простая программа, и она работает без ошибок. Я читал в Интернете и интересовался unit test, поэтому я создал тестовый проект:

Файл > Создать > Проект... > Установленный > Шаблоны > Visual С++ > Тест > Нативный Unit Test Проект >

Название: UnitTest1 Решение: Добавить в решение Затем местоположение автоматически переключается на путь текущего открытого решения Это структура папок решения:

Folder structure

Я только редактировал файл 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
        }

    };
}

Но я получаю ошибку LNK2019: неразрешенный внешний символ. Я знаю, что реализация функции multiple отсутствует. Я попытался удалить файл function.cpp, и я заменил объявление на определение, и он запустился. Но написать декларацию и определение в том же файле не рекомендуется. Как я могу исправить эту ошибку, не делая этого? Должен ли я заменить #include "../MyProjectTest/function.cpp" на файл unittest.cpp? (Я не очень хорошо разбираюсь в английском языке.)

4b9b3361

Ответ 1

Один вариант - включить function.cpp в ваш проект UnitTest1, но это может быть не самая идеальная структура решения. Короткий ответ на вашу проблему заключается в том, что при создании проекта UnitTest1 компилятор и компоновщик понятия не имеют, что function.cpp существует, а также не имеет никакого связывания, содержащего определение multiple. Способ исправить это использование библиотек ссылок.

Поскольку ваши модульные тесты находятся в другом проекте, я предполагаю, что вы намерены сделать этот проект автономной программой модульного тестирования. С помощью функций, которые вы тестируете, расположенных в другом проекте, можно построить этот проект либо в динамически, либо в статически связанной библиотеке. Статические библиотеки связаны с другими программами во время сборки и имеют расширение .lib, а динамические библиотеки связаны во время выполнения и имеют расширение .dll. Для моего ответа предпочитаю статические библиотеки.

Вы можете превратить свою первую программу в статическую библиотеку, изменив ее в свойствах проектов. На вкладке "Общие" должна быть опция, для которой проект должен быть установлен в исполняемый файл (.exe). Вы можете изменить это на .lib. Файл .lib будет создан в том же месте, что и .exe.

В проекте UnitTest1 вы можете перейти к его свойствам, а на вкладке Linker в категории Дополнительные библиотечные каталоги добавьте путь к созданию MyProjectTest. Затем для дополнительных зависимостей на вкладке Linker - Input добавьте имя вашей статической библиотеки, скорее всего, MyProjectTest.lib.

Это должно позволить вашему проекту строить. Обратите внимание, что, делая это, MyProjectTest не будет автономной исполняемой программой, если вы не измените свои свойства сборки по мере необходимости, что было бы менее идеальным.

Ответ 2

В дереве решений Visual Studio щелкните правой кнопкой мыши по проекту "UnitTest1", затем "Добавить" → "Существующий элемент" → выберите файл../MyProjectTest/function.cpp

Ответ 3

Так как я хочу, чтобы мой проект компилировался в автономный EXE, я связал проект UnitTest с файлом function.obj, сгенерированным из функции function.cpp, и он работает. Щелкните правой кнопкой мыши на проекте "UnitTest1" > "Свойства конфигурации" > "Компоновщик" > "Enter" > "Дополнительные зависимости" > "Добавить\MyProjectTest\Debug\function.obj"

Ответ 4

оказалось, что я использовал файлы .c с файлами .cpp. переименование .c в .cpp решило мою проблему.

Ответ 5

Я только что столкнулся с этой проблемой в Visual Studio 2013. По-видимому, сейчас не хватает двух проектов в одном решении и установки зависимостей. Вам нужно добавить ссылку на проект между ними. Для этого:

  • Щелкните правой кнопкой мыши проект в поиске решения
  • Нажмите Добавить = > Ссылки...
  • Нажмите кнопку "Добавить новую ссылку"
  • Установите флажки для проектов, на которые этот проект опирается
  • Нажмите "ОК"

Ответ 6

Еще один способ получить эту ошибку компоновщика (как я был) - это экспортировать экземпляр класса из dll, но не объявили этот класс как импорт/экспорт.

 #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

Итак, хотя в основном я экспортировал только экземпляр класса Book под названием book выше, мне пришлось объявить класс book классом экспорта/импорта, а в противном случае вызов book.WordCount() в другой dll вызывал ошибка связи.

Ответ 7

Я только что обнаружил, что LNK2019 возникает во время компиляции в Visual Studio 2015, если забыть предоставить определение объявленной функции внутри класса.

Ошибка компоновщика была очень загадочной, но я сузил то, чего не хватало, прочитав эту ошибку и предоставив определение вне класса, чтобы очистить это.

Ответ 8

Для меня работает, если я добавлю эту строку ниже в .vcxproj в itemGroup cpp файле, который связан с файлом заголовка.

<ClCompile Include="file.cpp" />

Ответ 9

Это случилось со мной, поэтому я решил поделиться своим решением так же просто:

Проверьте набор символов обоих проектов в Свойства конфигурации Общие Набор символов

В моем проекте UnitTest использовался набор символов по умолчанию Multi-Byte, в то время как мои библиотеки, в которых Юникод.
Моя функция использовала параметр TCHAR. В результате в моем lib мой TCHAR был преобразован в WCHAR, но он был char * мой UnitTest: символ был другим, потому что параметры в конце концов не были одинаковыми.