C++ 链接器错误-链接两个“;申请书;键入项目以使用Google测试

C++ 链接器错误-链接两个“;申请书;键入项目以使用Google测试,c++,linker-errors,googletest,C++,Linker Errors,Googletest,我正在尝试用Google test测试一个函数 似乎一切都设置正确,而且在没有gtest的情况下,它的构建和执行都很好。。。(代码有点复杂,所以我不能在这里列出所有的源文件,但如果不添加gtest,这些文件将正确链接,并正常运行) 这是一个应用程序类型的项目。它有许多库依赖项。。。无关紧要 测试项目将作为一个单独的项目添加到解决方案中。它将测试项目作为依赖项。测试项目的.h文件仅指向gtest。。。.cpp(不是main,它是标准的InitGoogleTest main)添加了自己的头文件,即被

我正在尝试用Google test测试一个函数

似乎一切都设置正确,而且在没有gtest的情况下,它的构建和执行都很好。。。(代码有点复杂,所以我不能在这里列出所有的源文件,但如果不添加gtest,这些文件将正确链接,并正常运行)

这是一个应用程序类型的项目。它有许多库依赖项。。。无关紧要

测试项目将作为一个单独的项目添加到解决方案中。它将测试项目作为依赖项。测试项目的.h文件仅指向gtest。。。.cpp(不是main,它是标准的InitGoogleTest main)添加了自己的头文件,即被测试项目的头文件,并具有如下所示的测试

当项目构建时,即使它是一个应用程序,也会自动创建TestedProject.lib。我已经将TestedProject.lib作为库依赖项添加到TestProject(链接中)

实施:

bool x::myFunction(std::string a, double b, bool c)
{
  // implementation
  return false;
}

somewhere_else
{
  x x_instance;
  y = x_instance.myFunction("a", 1, false);   // works, all builds, executes, life is great
}
添加单元测试:

class TheTest : public ::testing::Test
{
protected:
    x x_instance;
};

TEST_F(TheTest, Fail)
{
    EXPECT_FALSE(x_instance.myFunction("a", 1, false));     
}
没有建立。链接错误(修改,如上面的示例代码,名称简化,我希望我没有弄乱内容)

错误2错误LNK2019:未解析的外部符号

“public:bool\uuu thiscall x::myFunction(class std::basic\u string所以我会有一个答案:

对于我的问题,我有两种解决方案:

1) 将应用程序项目分为两个项目,一个项目将成为一个库,其中包含大部分代码;另一个项目将是一个应用程序,其中包含一个很小的main(),用于调用实际代码的入口点(如参数解析方法或其他)

然后,我可以添加一个单元测试项目来测试库

2) 不要打断项目。添加gtest项目,不要创建任何依赖项。将要测试的文件添加到gtest项目中。gtest项目将是一个单独的可执行文件…它需要满足所有要求。(优点:测试没有依赖项)


我更喜欢第一个版本。

还有另一个解决方案,我更喜欢,因为这意味着您可以避免更改主项目:

向主项目中添加“生成后操作”,以便为完全相同的源文件创建静态库。 然后,您可以简单地将此依赖项添加到您的gtest项目中

每次编译主项目时,它都会构建应用程序和静态库

这样,您就不必创建第三个项目并保持配置同步


希望有帮助。

还有另一种解决方案

只需为Google测试框架创建一个新项目。 (当然,在您现有的应用程序解决方案下)

然后,在确保所有Google测试框架设置正确后。 (您可以在新创建的解决方案下对其进行测试)

从主项目中手动包含您想要测试的代码(使用Add->Existing Item),然后您可以测试代码,而无需生成额外的库

这其中的好处是,当您测试一些需要windows中的DLL的应用程序时,它要求应用程序使用多线程调试DLL。 (在您的项目属性设置中,转到C/C++->代码生成->运行时库查看您得到了什么)

Google测试框架使用了一个非常不同的运行库(多线程调试(/MTd))

在链接阶段,编译器会抱怨说,它很难将应用程序生成的库与多线程DLL和google框架的库(多线程)链接起来


通过这种方式,您可以避免这两个项目的依赖性问题。(一个用于/Mtd,一个用于/Md)

通常您会有一个库(或一些库),它构成了您自己代码的大部分,还有一个exe/应用程序,它只有一个链接库的
main
函数。通过这种方式,您可以拥有另一个项目,该项目具有不同的
main
和一堆测试代码(如果需要,可以在多个文件中),这些代码还链接了您的库。你不应该期望能够将2个应用程序与2
main
s链接。谢谢。这就是我最终实现它的原因,我一问完问题,真的-当我找到我添加的链接时,这个链接帮助我找到了答案。我不得不创建一个单独的项目,只提取一个很小的main()我确实希望能够用main()链接2个应用程序,但我花了很长时间才发现我做不到。我确信某个地方有“链接错误手册”,或“可以测试的手册”,或“其他人尝试过但失败的东西,所以尽量不要犯同样的错误。”“手册。。。我想读。是的,我也是!编译器错误通常比链接器错误更容易解决。具体来说,设置应该是:打开主项目属性,选择生成事件->生成后事件选项卡。使用命令lib/NOLOGO/OUT:“$(TargetPath).lib”“$(ProjectDir)\$(Configuration)*.obj”,这样将生成$(ProjectName).exe.lib文件和.exe文件,这有利于静态链接到单元测试项目。此答案应被接受为最佳答案@yc2986的评论也有帮助。但对于我的例子,我需要稍微修改建议的命令:lib/NOLOGO/OUT:“$(TargetPath.lib”“$(ProjectDir)obj\$(配置)\$(PlatformTarget)*.obj”1/3第2条注释中的命令有一个问题:它假设解决方案中的文件夹结构,在Win32和x64平台上默认的Visual Studio文件夹结构上不起作用。2/3 Visual Studio将.obj文件放入中间文件夹,您可以在项目属性>配置属性>常规>中间目录中找到并设置。Win32平台上的设置为
$(配置)`将验证为
$(ProjectDir)$(配置)`。但是在x64平台上,中间目录设置为
$(平台)\$(配置)`这将被验证为
$
class TheTest : public ::testing::Test
{
protected:
    x x_instance;
};

TEST_F(TheTest, Fail)
{
    EXPECT_FALSE(x_instance.myFunction("a", 1, false));     
}
Error   2   error LNK2019: unresolved external symbol 
"public: bool __thiscall x::myFunction(class std::basic_string<char,struct std::char_traits<char>,double,bool)" 
(?myFunction@x@@QAE_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@00000NNNN_N1@Z) 
referenced in function "private: virtual void __thiscall TheTest_Fail_Test::TestBody(void)" 
(?TestBody@TheTest_Fail_Test@@EAEXXZ)   C:\path\file.obj