【问题标题】:How can I solve the error LNK2019: unresolved external symbol - function?如何解决错误 LNK2019: unresolved external symbol - function?
【发布时间】:2013-11-22 01:50:33
【问题描述】:

我收到此错误,但我不知道如何解决。

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

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

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

菜单文件新建项目...已安装模板Visual C++测试原生单元测试项目

名称: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 文件,并将声明替换为定义,然后它运行了。但不建议将声明和定义写在同一个文件中。

如果不这样做,如何解决此错误?我应该用文件 unittest.cpp 中的#include "../MyProjectTest/function.cpp" 替换它吗?

【问题讨论】:

标签: c++ testing error-handling lnk2019


【解决方案1】:

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

【讨论】:

  • 请注意,实际文件并未复制或移动到 ProjDir。
  • 此方法解决了尝试将 c++ lib 添加到 CLI 项目时发生的类似问题。
【解决方案2】:

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

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

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

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

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

【讨论】:

  • 在 'Linker->Input Tab' 中,我必须为静态库添加前缀 '(OutDir)',即 '$(OutDir)MyProjectTest.lib',尽管 'MyProject' 和'MyTestProject' 保存在同一根文件夹中。
  • 所以每次你想运行单元测试你都应该把你的被测项目转换成一个静态库,而每次你真正想运行你的程序时你把它转换回一个可执行文件,这是怎么回事解决方案?
  • 如果 MyProjectTest 是一个 dll,我们可以测试它吗?我们只是添加导入库还是必须添加 obj 文件?
  • "您可以通过在项目属性中更改它来将您的第一个程序变成一个静态库。在“常规”选项卡下应该有一个选项,其中项目设置为构建为可执行文件 (.exe) .您可以将其更改为 .lib。.lib 文件将构建到与 .exe 相同的位置" 这样做对我的情况来说已经足够了。其余的已经由 VS 处理了。
【解决方案3】:

由于我希望我的项目编译为独立的 EXE 文件,我将 UnitTest 项目链接到从 function.cpp 生成的 function.obj 文件,它有效。

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

【讨论】:

  • MyProjectTest是dll的情况如何?可以设置吗?
  • 如果我们有很多 obj 文件。我们可以添加一些像 *.obj 这样的东西吗?您的解决方案对我有用,但我不想手动添加每个新的 obj 文件。
【解决方案4】:

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

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

【讨论】:

【解决方案5】:

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

【讨论】:

    【解决方案6】:

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

    <ClCompile Include="file.cpp" />
    

    【讨论】:

      【解决方案7】:

      另一种获得此链接器错误的方法(就像我一样)是,如果您正在从 DLL 文件中导出一个类的 instance,但没有将该类本身声明为导入/导出。

      #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 类声明为导出/导入类,否则调用 @987654324另一个 DLL 文件中的 @ 导致链接错误。

      【讨论】:

        【解决方案8】:

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

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

        【讨论】:

        • 在某些情况下的问题是包含类定义的标头都很好地引用/包含,但它们对应的 cpp 可能不是链接器的made available。最好的检查方法是在解决方案资源管理器中浏览项目外部依赖项。不过,对于 VS 来说,就该错误发出某种文件存在/包含警告将是有益的。
        【解决方案9】:

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

        我的 UnitTest 项目使用默认字符集 多字节,而我的库是 Unicode

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

        因此,在我的库中,我的 TCHAR转换WCHAR,但它是一个 char* 在我的 UnitTest 中:符号不同,因为最终参数确实不一样。

        【讨论】:

          【解决方案10】:

          在 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,后者是如果您需要测试非公共成员并且需要将测试与您的真实代码放在同一个项目中。

          请注意,您要测试的内容需要使用__declspec(dllexport) 导出。详情请见Exporting from a DLL Using __declspec(dllexport)

          【讨论】:

            【解决方案11】:

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

            【讨论】:

            • 你能修正你答案的最后一部分吗(似乎可以理解)?也是用户界面元素的实际拼写。 没有“编辑:”、“更新:”或类似的 - 问题/答案应该看起来好像是今天写的。
            【解决方案12】:

            在你的头文件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 文件,生成具有预期符号名称的对象

            【讨论】:

              猜你喜欢
              • 2017-03-30
              • 2020-05-07
              • 1970-01-01
              • 2021-07-19
              • 1970-01-01
              • 2013-01-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多