2016-08-05 124 views
1

我试图创建一个可以在Windows(VS2015)上读取多个文件格式的程序(C++)。 为了做到这一点,我使用Project for MyProgram(这是主程序)和MyLibrary(包含用于不同文件格式的几个解析器)的项目创建了一个解决方案。 在MyProgram中,我根据程序输入创建了一些解析器对象。将程序链接到静态库,将其自身链接到另一个库

一切工作正常。

不过,我试图创建一个新的文件格式分析器(NiftiParser)使用外部库,nifticlib,我下载并编译(静态库)。

所以我创建了NiftiParser类,实现一些方法,并在内部,它调用nifticlib。 我在项目属性中添加了包含目录和库目录,并且编译时没有错误。 然后我得到了一个已创建的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> >)" ([email protected]@[email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@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 ========== 

我不知道明白为什么会这样。我试图将包含的路径和nifticlib的库目录添加到MyProgram项目,但我仍然有一些问题。

我不知道理解什么是Visual Studio的(我曾经在Linux上工作)编译/链接过程。

在我看来,如果它是一个静态库,和该连接部分只有当我试图编译程序本身发生的项目只编译。 我对不对?

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

谢谢。

PS:另外我注意到,nifticlib我的安装目录仅包含头文件和.LIB。我是否也需要有.cpp,或者函数是否已经包含在.lib中?好吧,显然建立一些东西作为一个静态库没有链接到任何东西,所以这可能是为什么我没有得到任何问题编译Parser.lib,因为它不链接到nifticlib,但MyProgram需要它。 所以我应该只在我的Parser项目中包含nitficlib的dir目录,并将Parser.lib和nifticlib放入我的MyProgram项目中?

回答

3

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

同样,在VS你不仅需要设置路径到库目录,但是明确表示库文件中。这通常在项目属性 - >链接器 - >输入 - >其他依赖关系上完成。请注意,在Windows中,您只需输入完整的库名称(MyLib。LIB),而不是部分之间的lib .A

还要注意的是,在Windows下你不能链接到一个动态库文件(.dll)的二进制文件。您将需要一个导入库(.lib)。

当您创建一个静态库,工具链不能解决外部引用。这就是为什么你没有引用nifticlib而编译好.lib。

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

的经验法则可以制定这样的:

  • 如果只在MyLibrary是使用nifticlib的标题,链接库中与第三方一个
  • 如果MyProgram还使用nifticlib的标题(并且实际上从它们调用函数),建立MyProgram时最好链接nifticlib

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

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

编辑:如果你希望你的静态库与外部组件从另一个静态链接库,你需要去项目属性 - >图书馆 - >常规 - >附加依赖,并把外部的.lib有

+0

非常感谢你对这个非常完整的答案。我现在应该可以弄清楚了。虽然 还有一个问题,当您将库添加到输入 - >附加依赖,你需要指定的完整路径,或在图书馆的只是名字? – whiteShadow

+0

只是名字。目录路径在VC++目录 - >库目录中指定。另外,如果MyLibrary和MyProgram项目都在同一解决方案中,则根本不需要担心库目录。 VS应该能够正确地计算出它们,包括构建应用程序的不同版本(调试/版本,x86/x64等)时的情况。只需将库名称放入依赖项中即可。 –

+0

非常感谢您的帮助。 我觉得VS里有什么令我困惑的是,在哪里放置信息。我并不十分熟悉解决方案,项目等的概念,以及在何处放置库目录等。在Linux上,我使用的是命令行或cmake,我觉得这很容易。但由于:d – whiteShadow

相关问题