116

我收到此错误,但我不知道如何修复它。

我正在使用 Visual Studio 2013。我将解决方案命名为MyProjectTest 这是我的测试解决方案的结构:

结构

-函数.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;
}

我是初学者;这是一个简单的程序,它运行没有错误。上网看了一下,对单元测试产生了兴趣,于是创建了一个测试项目:

菜单文件新建项目...已安装模板Visual C++测试本机单元测试项目→</p>

名称:UnitTest1
解决方案:添加到解决方案

然后位置自动切换到当前打开的解决方案的路径。

这是解决方案的文件夹结构:

文件夹结构

我只编辑了文件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 替换它吗?

4

12 回答 12

89

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

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

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

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

这应该允许您的项目构建。请注意,这样做MyProjectTest不会成为独立的可执行程序,除非您根据需要更改其构建属性,这不太理想。

于 2013-11-10T05:47:48.097 回答
42

在 Visual Studio 解决方案树中,右键单击项目“UnitTest1”,然后添加现有项目→ 选择文件../MyProjectTest/function.cpp

于 2013-11-10T05:09:20.107 回答
21

由于我希望我的项目编译为独立的 EXE 文件,因此我将 UnitTest 项目链接到从 function.cpp 生成的function.obj文件并且它可以工作。

右键单击“UnitTest1”项目→配置属性链接器输入附加依赖项→添加“..\MyProjectTest\Debug\function.obj”

于 2015-06-05T13:17:56.070 回答
11

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

  1. 右键单击解决方案探索中的项目
  2. 单击添加 => 引用...
  3. 单击添加新引用按钮
  4. 选中此项目所依赖的项目的复选框
  5. 点击确定
于 2015-12-22T21:07:19.940 回答
8

另一种获得此链接器错误的方法(就像我一样)是,如果您正在从 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 文件中调用会导致链接错误。

于 2017-10-05T19:21:41.147 回答
8

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

于 2016-06-04T19:39:08.943 回答
3

在Configuration PropertiesGeneralCharacter Set中检查两个项目的字符集。

我的 UnitTest 项目使用默认字符集Multi-Byte而我的库是Unicode

我的函数使用TCHAR作为参数。

结果,在我的库中,我的TCHAR转换WCHAR,但在我的 UnitTest 中它是一个char * :符号不同,因为最终参数实际上并不相同。

于 2018-02-28T15:44:17.457 回答
2

我刚刚发现,LNK2019如果忘记为类中声明的函数提供定义,则会在 Visual Studio 2015 的编译过程中发生这种情况。

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

于 2017-10-10T18:10:41.667 回答
1

就我而言,在“property”->“general”中将cpp文件设置为“C/C++ compiler”,解决LNK2019错误。

于 2020-04-22T09:59:04.830 回答
1

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

有关更多详细信息,请参阅MSDN 博客中的 Visual Studio 中的 C++ 单元测试。您还可以检查Write unit tests for C/C++ in Visual Studio以及Use the Microsoft Unit Testing Framework for C++ in Visual Studio,后者是如果您需要测试非公共成员并且需要将测试放在同一个项目中作为您的真实代码。

请注意,您要测试的内容需要使用__declspec(dllexport). 有关详细信息,请参阅使用 __declspec(dllexport) 从 DLL 导出

于 2018-06-25T02:29:17.823 回答
0

对我来说,如果我在连接到头文件.vcxproj的cpp 文件中添加下面的这一行,它就可以工作。itemGroup

<ClCompile Include="file.cpp" />
于 2017-08-29T13:23:16.487 回答
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 文件,生成具有预期符号名称的对象

于 2021-05-10T14:16:38.030 回答