将程序链接到静态库,将自身链接到另一个库

时间:2016-08-05 01:55:19

标签: c++ visual-studio-2015 static-libraries linker-errors

我正在尝试在Windows(VS2015)上创建一个可以读取多种文件格式的程序(C ++)。 为了做到这一点,我创建了一个带有Project for MyProgram(这是主程序)的解决方案,以及一个MyLibrary项目(包含几个不同文件格式的解析器)。 在MyProgram中,我根据程序输入创建了一些解析器对象。

一切都运转良好。

但是,我尝试创建一个新的文件格式解析器(NiftiParser),它使用我下载和编译的外部库nifticlib(作为静态库)。

所以我创建了我的NiftiParser类,它实现了一些方法,在内部,它调用了nifticlib。 我在项目属性中添加了include dir和library dir,并且编译时没有错误。 然后我得到了一个已经创建的Parser.lib。

但是,当我尝试编译MyProgram时,我收到一条关于nifticlib库的某些函数未解析的错误:

1>------ Build started: Project: Parser, Configuration: Debug x64 ------
1>  nifti_parser.cc
1>  Parser.vcxproj -> C:\Users\Laurent\Documents\C++-build\Projects\Parser\Debug\Parser.lib
2>------ Build started: Project: MyProgram, Configuration: Debug x64 ------
2>Parser.lib(nifti_parser.obj) : error LNK2019: unresolved external symbol nifti_image_read referenced in function "public: __cdecl NiftiParser::NiftiParser(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0NiftiParser@@QEAA@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
2>C:\Users\Laurent\Documents\C++-build\Projects\Debug\MyProgram.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 1 succeeded, 1 failed, 3 up-to-date, 0 skipped ========== 

我不确定为什么会这样。我试图将include的路径和nifticlib的库目录添加到MyProgram项目中,但我仍有一些问题。

我不确定Visual Studio的编译/链接过程是什么(我以前在Linux上工作)。

在我看来,如果项目是静态库,则只编译项目,而链接部分仅在我尝试编译程序本身时才会发生。 我是对的吗?

另外,我不确定nifticlib应链接到哪里。应该是Parser.lib(我使用库的功能)还是直接到程序?

谢谢。

PS:我也注意到我的nifticlib安装目录只包含头文件和.lib。我是否也需要.cpp,或者函数是否已包含在.lib中?

编辑:好吧,显然构建一个静态库并没有将它链接到任何东西,所以这可能就是为什么我没有遇到编译Parser.lib的任何问题,因为它没有链接到nifticlib,但MyProgram需要它。 那么我应该只在我的Parser项目中包含nitficlib的include目录,并将Parser.lib和nifticlib放在我的MyProgram项目中吗?

1 个答案:

答案 0 :(得分:3)

Visual Studio的编译/链接与Linux工具链中发生的情况没有太大差别。在创建二进制文件(可执行文件或动态库)时,必须解析所有外部符号。在GCC中,您必须向链接器指明库。命令行选项-lmath将告诉链接器从为库搜索设置的路径之一加载 libmath.a ,并在构建可执行映像时使用它。

同样,在VS中,您不仅需要设置库目录的路径,还需要显式指示库文件。这通常在项目属性上完成 - &gt;链接器 - &gt;输入 - &gt;其他依赖项。请注意,在Windows中,您只需输入完整的库名称( MyLib.lib ),而不是 lib .a

另请注意,在Windows中,您无法链接到动态库(.dll)的二进制文件。你需要一个导入库(.lib)。

创建静态库时,工具链不会解析外部引用。这就是为什么你.lib编译好了而没有引用nifticlib。

至于你应该在哪里链接nifticlib,这取决于具体情况。如果只有你的MyLibrary将使用nifticlib的功能,那么将它与你的静态库链接是明智的。但是,如果有一天您希望在MyProgram中直接使用nifticlib中的某些函数,则链接时可能会发生冲突。在这种情况下,您只需在构建MyProgram时链接nifticlib。

拇指规则可以这样表达:

  • 如果只有MyLibrary使用nifticlib的标题,请将您的图书馆与第三方链接
  • 如果MyProgram也使用nifticlib的头文件(并实际调用它们的函数),最好在构建MyProgram时链接nifticlib

这不是一个严格的描述,有更复杂的情况,但基础是这样的。

不,当您从另一个项目链接到该库时,您不需要在构建静态库时使用的cpp文件。库.cpp的内容已经以目标代码的形式包含在静态lib文件中。

编辑:如果您希望将静态库与其他静态库的外部链接相关联,则需要转到项目属性 - &gt;图书馆员 - &gt;一般 - &gt;其他依赖项并将外部.lib放在那里