函数定义在cpp文件中时链接器错误

时间:2015-07-04 22:42:49

标签: c++ linker

我的解决方案有三个项目:GoogleTest(用于使用Google测试),Vi(用于大部分逻辑)和ViTests(用于使用Vi的单元测试)。 ViTests项目引用Vi项目和Google Test项目。

Vi在v1.h中有以下代码

#pragma once

namespace Vi
{
    class Vi1
    {
    public:
        int SomeInt();
    };
}

匹配v1.cpp

#include "vi1.h"

namespace Vi
{
    int Vi1::SomeInt()
    {
        return 123;
    }
}

ViTests中的测试功能如下

TEST(Vi1Foo, SomeIntIsSame)
{
    Vi1 v = Vi1{};
    EXPECT_EQ(123, v.SomeInt());
}

链接器错误表示存在未解析的符号SomeInt。但是,我可以通过内联函数使链接器错误消失:

namespace Vi
{
    class Vi1
    {
    public:
        int SomeInt() { return 123; }
    };
}

为什么单元测试项目放在单独的cpp文件中时找不到SomeInt函数定义?

感谢。

额外的细节很有用:我正在使用Visual Studio 2015。

错误消息:

Error   LNK2019 unresolved external symbol "public: int __thiscall Vi::Vi1::SomeInt(void)" (?SomeInt@Vi1@Vi@@QAEHXZ) referenced in function "private: virtual void __thiscall ViTests::Vi1Foo_SomeIntIsSame_Test::TestBody(void)" (?TestBody@Vi1Foo_SomeIntIsSame_Test@ViTests@@EAEXXZ) Vi_Tests    C:\Users\MyName\Vi\Vi_Tests\Vi_Tests.obj    1

项目类型: Vi是Win32应用程序,ViTests是Win32控制台应用程序,GoogleTest是一个静态库。

2 个答案:

答案 0 :(得分:2)

我是在一个愚蠢的错误假设下工作的。我假设VS只是拾取cpp文件,因为我引用了包含它们的项目并包含正确的头文件,但事实并非如此。

nabijaczleweli说我应该“使用函数定义链接到文件”。经过一些网上探索后,我发现了如何做到这一点。我发现this张贴了一个解决方案。必须将cpp文件本身添加到测试项目中。这是通过右键单击ViTests,选择“添加现有文件”并选择vi1.cpp来完成的。

这很有用,但我对这个解决方案很不满意,因为我必须在需要时添加这些文件。我发现我可以绕过这个将Vi项目的类型改为静态库。这被描述为here。 Michael Burr的评论描述了一种链接到也可以工作的目标文件的方法。

如果没有这个帖子中海报的帮助,我不会这么快就想到这个。非常感谢你们。

答案 1 :(得分:1)

您没有指定项目的类型。我猜测它们是DLL,因此您希望在它们之外使用的非内联函数或类需要导出:在源处声明为__declspec(dllexport)或在DEF文件中列出。

如果你使用__declspec(dllexport),请记住__declspec(dllimport)消费项目中的函数。这通常通过在.h文件中用作限定符的宏来实现,该宏在不同项目中的解析方式不同。