2013-11-10 3 views
53

Я получаю эту ошибку, но я не знаю, как ее исправить.Как решить ошибку 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; 
} 

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

File> New> Project ...> Installed> Шаблоны> Visual C++> Test> Project Test Native Unit>

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

+0

Возможный дубликат [Что такое неопределенная ссылка/неразрешенная ошибка внешнего символа и как ее исправить?] (Http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved- external-symbol-error-and-how-do-i-fix) – WhozCraig

+3

** BE CAREFUL ** В * среде Windows *, статические библиотеки имеют расширение '.LIB'. Чтобы усложнить ситуацию ... библиотеки динамических ссылок (например, '* .DLL') могут иметь сопровождающую * библиотеку импорта *, которая также имеет расширение' .LIB'. В этой библиотеке импорта перечислены все полезные свойства, предоставленные '* .DLL'. Для получения дополнительной информации, пожалуйста, прочитайте: [Руководство для начинающих по компоновщикам] (http://www.lurklurk.org/linkers/linkers.html) – Pressacco

+0

Зачем ему быть осторожным? –

ответ

46

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

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

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

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

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

30

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

9

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

6

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

  1. правой кнопкой мыши по проекту в решении изучить
  2. Нажмите кнопку Добавить => Ссылки ...
  3. Нажмите Add New Reference кнопку
  4. флажки для тех проектов, которые этот проект основан на
  5. Нажмите OK
6

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

0

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

<ClCompile Include="file.cpp" /> 
1

Другим способом вы можете получить эту ошибку компоновщика (как я), если вы экспортируете экземпляр класса из библиотеки 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.WordCount() в другой библиотеке DLL причинял ошибка связи.

0

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

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

0

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

Проверьте набор символов обоих проектов в Configuration Properties ->Общие ->Набор символов

проект My UnitTest использует набор символов по умолчанию многобайтной в то время как мой ЛИЭС где в Unicode.
Моя функция использовала в качестве параметра TCHAR. В результате в моем Lib мой TCHAR был трансформируются в WCHAR, но это был символ * на моем UnitTest: символ различались, так как параметры были действительно не то же самое, в конце концов.