C ++:链接库和添加包含目录之间的区别

时间:2011-08-17 16:17:38

标签: c++ compiler-construction linker

相当多的标题总结了它。

如果我想使用图书馆,我不确定这两者之间的区别。

谢谢!

3 个答案:

答案 0 :(得分:48)

一般来说,你需要两者。

包含文件包含声明类型,函数原型,inline函数,#define s,...,一般来说每个有关库的信息编译文件时需要注意编译器

相反,静态库包含库函数的实际目标代码。如果标头包含原型,则静态库包含函数的(已编译)定义,即链接器将与您链接的对象模块。

如果您只包含头文件而没有链接静态库,链接器会抱怨缺少定义,因为您将在标头中使用声明的函数,但不是定义< / em> anywhere(=没有实现)。另一方面,如果您只链接静态库而不提供标题,编译器会抱怨未知标识符,因为它不会对您正在使用的库符号有任何线索。

这个概念与编译多文件项目非常相似:要访问在其他.cpp中编写的定义,您需要只包含一个包含其声明的标头,并且最后的链接器链接在一起各种对象模块。

就dll而言,通常提供导入库;导入库就像静态库,但是,它们不包含库的所有代码,而是包含将函数调用到dll中的小存根。每次在一个目标模块中遇到对库函数的调用时,链接器会将其定向到存根,然后存根将其重定向到代码中的dll 1 。总而言之,在Windows上处理dll时,通常会有.h(prototypes / ...),.lib(链接的导入库,包含存根)和{{1} (包含库的实际代码的动态链接库)。

顺便说一下,有些库只是“标题”(你可以在boost中找到很多),这意味着它们的所有代码都被放入标题中,因此不需要静态库。这些库通常只由内联代码(函数/类/ ...)和模板组成,不需要单独的定义。

通常这样做是因为静态库是丑陋的野兽,原因如下:

  • 你必须明确地链接他们;
  • 因为它们直接链接到您的代码,所以它们必须使用完全相同的C / C ++运行时库,这意味着,至少在Windows上,分发静态库(不同的编译器,不同的编译器版本,不同的配置)是不切实际的相同的编译器使用不同的标准库,为这些方面的每个组合分配静态库至少是不切实际的;;
  • 因此,一般情况下,您必须首先在您自己的静态库版本上编译,然后链接它。

将所有这些与仅包含头文件......:)

进行比较
  1. 实际上,现代工具链可以识别这些存根并避免额外的间接步骤。有关详细信息,请参阅Raymond Chen的this series

答案 1 :(得分:22)

编译器需要知道包含目录,因为它需要包含您要使用的库的头文件( interface )。

链接器需要知道库目录,因为它需要将可执行文件链接到库的(预编译的)实现

另见What are the differences between a compiler and a linker?

答案 2 :(得分:3)

包含目录仅适用于头文件,通常仅提供函数/方法签名。您需要链接到库才能访问其实际的目标代码。

请参阅this question