我的解决方案有三个项目: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是一个静态库。
答案 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文件中用作限定符的宏来实现,该宏在不同项目中的解析方式不同。