如何解决错误LNK2019:未解析的外部符号 - 功能?

时间:2013-11-10 04:47:55

标签: c++ testing error-handling 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;
}

我是初学者;这是一个简单的程序,它运行没有错误。 我在互联网上阅读并对单元测试感兴趣,所以我创建了一个测试项目:

档案&gt;新&gt;项目...&gt;已安装&gt;模板&gt; Visual C ++&gt;测试&gt;原生单元测试项目&gt;

名称: 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文件,我用定义替换了声明,然后运行。但不建议在同一文件中写入声明和定义。 如何在不这样做的情况下修复此错误?我应该用文件unittest.cpp中的#include "../MyProjectTest/function.cpp"替换吗? (我不太擅长英语。谢谢)

12 个答案:

答案 0 :(得分:64)

一种选择是在function.cpp项目中加入UnitTest1,但这可能不是最理想的解决方案结构。对您的问题的简短回答是,在构建UnitTest1项目时,编译器和链接器不知道function.cpp存在,也没有任何链接包含multiple的定义。解决这个问题的方法是使用链接库。

由于您的单元测试属于不同的项目,我假设您的目的是使该项目成为一个独立的单元测试程序。使用您正在测试的功能位于另一个项目中,可以将该项目构建为动态或静态链接的库。静态库在构建时链接到其他程序,扩展名为.lib,动态库在运行时链接,扩展名为.dll。对于我的回答,我更喜欢静态库。

您可以通过在项目属性中更改它来将第一个程序转换为静态库。 “常规”选项卡下应该有一个选项,其中项目设置为构建为可执行文件(.exe)。您可以将其更改为.lib.lib文件将构建到与.exe相同的位置。

在您的UnitTest1项目中,您可以转到其属性,并在“附加库目录”类别的“链接器”选项卡下,添加MyProjectTest构建的路径。然后,对于Linker - Input选项卡下的Additional Dependencies,添加静态库的名称,很可能是MyProjectTest.lib

这应该允许您的项目构建。请注意,通过执行此操作,MyProjectTest将不是独立的可执行程序,除非您根据需要更改其构建属性,这将不太理想。

答案 1 :(得分:34)

在Visual Studio解决方案树中,右键单击项目'UnitTest1',然后添加 - > gt;现有项目 - &gt;选择文件../ MyProjectTest / function.cpp

答案 2 :(得分:13)

由于我希望我的项目编译为独立的EXE,我将UnitTest项目链接到从function.cpp生成的function.obj文件,它可以工作。 右键单击'UnitTest1'项目&gt;配置属性&gt;链接器&gt;输入&gt;附加依赖性&gt;添加“.. \ MyProjectTest \ Debug \ function.obj”

答案 3 :(得分:8)

我刚刚在Visual Studio 2013中遇到了这个问题。显然现在,在同一个解决方案中设置两个项目并设置依赖项是不够的。您需要在它们之间添加项目引用。要做到这一点:

  1. 右键单击解决方案探索中的项目
  2. 点击添加=&gt;引用...
  3. 单击“添加新引用”按钮
  4. 选中此项目所依赖的项目的框
  5. 点击确定

答案 4 :(得分:8)

原来我使用.c文件和.cpp文件。将.c重命名为.cpp解决了我的问题。

答案 5 :(得分:4)

另一种可以获得此链接器错误的方法(就像我一样)是从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类声明为导出/导入类否则在另一个dll中调用book.WordCount()会导致链接错误。

答案 6 :(得分:1)

我刚刚发现,如果忘记为类中的声明函数提供定义,那么在Visual Studio 2015中编译期间会出现LNK2019

链接器错误非常神秘,但我通过阅读错误缩小了所缺少的内容,并提供了类外的定义来清除它。

答案 7 :(得分:1)

在我的情况下,将属性中的cpp文件设置为“ C / C ++编译器”->一般可解决LNK2019错误。

答案 8 :(得分:0)

对我来说,如果我在.vcxproj cpp文件{@ 1}}中添加此行,该文件连接到头文件。

itemGroup

答案 9 :(得分:0)

这发生在我身上,所以我想我可能会分享我的解决方案,就像它一样简单:

配置属性 - &gt;中检查两个项目的字符集。 一般 - &gt; 字符集

我的UnitTest项目使用默认字符集多字节,而我的库在 Unicode 。 我的功能是使用 TCHAR 作为参数。 结果在我的lib中, TCHAR 转换 WCHAR ,但我的UnitTest上是 char * :符号不同,因为参数最终真的不一样。

答案 10 :(得分:0)

在Visual Studio 2017中,如果要测试公共成员,只需将真实项目和测试项目放在同一解决方案中,然后在测试项目中添加对真实项目的引用。

有关更多详细信息,请参见MSDN博客中的C++ Unit Testing in Visual Studio。您还可以检查Write unit tests for C/C++ in Visual StudioUse the Microsoft Unit Testing Framework for C++ in Visual Studio,后者是您是否需要测试非公开成员并且需要将测试与实际代码放在同一项目中。

请注意,您要测试的内容将需要使用return this.http.post(api.url, params) .map((res:any) => { 导出。有关更多详细信息,请参见Exporting from a DLL Using __declspec(dllexport)

答案 11 :(得分:0)

在你的头文件function.h的开头包含

#ifdef __cplusplus
extern "C" {
#endif

像这样:

    #ifndef MY_FUNCTION_H
    #define MY_FUNCTION_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    int multiple(int x, int y);

    #ifdef __cplusplus
    }
    #endif
    
    #endif

这将告诉单元测试项目上的 cpp 编译器将此 .h 文件编译为 C 文件,生成具有预期符号名称的对象