C++:链接库和添加包含目录之间的区别
很多标题都概括了.
如果我想使用库,我不确定两者之间的区别.
I'm not sure the difference between the two if i'd like to use a library.
谢谢!
推荐答案
一般来说,两者都需要.
In general, you need both.
包含文件包含类型的声明、函数的原型、inline
函数、#define
s、...,通常是所有信息关于编译器在编译文件时需要注意的库.
Include files contain declarations of types, prototypes of functions, inline
functions, #define
s, ..., in general every information about the library the compiler needs to be aware of when compiling your files.
相反,静态库包含库函数的实际目标代码.如果标头包含原型,则静态库包含(编译的)函数的定义,即链接器将与您的链接器链接的对象模块.
Static libraries, instead, contain the actual object code of the functions of the library. If the headers contain the prototypes, the static libraries contain the (compiled) definitions of the functions, i.e. the object modules that the linker will link with yours.
如果你只包含头文件而不链接静态库,链接器会抱怨缺少定义,因为你会在头文件中使用 declared 函数,而不是 defined 任何地方(即没有实现).另一方面,如果你只链接静态库而不提供头文件,编译器会抱怨未知标识符,因为它不知道你正在使用的库符号.
If you only included the header file without linking against the static library, the linker would complain about missing definitions, because you would be using functions declared in the header, but not defined anywhere (i.e. with no implementation). On the other hand, if you only linked the static library without providing the header, the compiler would complain about unknown identifiers, since it wouldn't have a clue about the library symbols you're using.
这个概念与编译多文件项目时非常相似:要访问用其他 .cpp
编写的定义,您只需在其声明中包含一个标头,并在end 将各种对象模块链接在一起.
The concept is very similar to when you compile a multi-file project: to access the definitions written in other .cpp
you need to include just a header with their declarations, and the linker in the end links together the various object modules.
就dll而言,通常会提供一个导入库;导入库类似于静态库,但它们不包含库的所有代码,而是包含将函数调用到 dll 中的小存根.每次在您的一个对象模块中遇到对库函数的调用时,链接器都会将其定向到存根,而存根又将其重定向到代码中的 dll1.总而言之,在 Windows 上处理 dll 时,您通常有一个 .h
(原型/...),一个 .lib
(您链接的导入库,包含stubs) 和一个 .dll
(包含库的实际代码的动态链接库).
As far as dlls are concerned, usually an import library is provided; import libraries are like static libraries, but, instead of containing all the code of the library, they contain small stubs that call the functions into the dll. Every time a call to a library function is encountered in one of your object modules, the linker directs it to the stub, which in turn redirects it to the code into the dll1. All in all, when dealing with dlls on Windows you usually have a .h
(prototypes/...), a .lib
(import library you link against, contains the stubs) and a .dll
(dynamic-linking library containing the actual code of the library).
顺便说一下,有些库是仅标头"的.(你可以在 boost 中找到很多),这意味着它们的所有代码都放在一个头文件中,因此不需要静态库.此类库通常仅由内联代码(函数/类/...)和模板组成,无需单独定义.
By the way, some libraries are "header only" (you can find many in boost), which means that all their code is put into a header, so no static library is needed. Such libraries are often just made of inline code (functions/classes/...) and templates, for which no separate definition is needed.
通常这样做是因为静态库是丑陋的野兽,原因如下:
Often this is done because static libraries are ugly beasts for several reasons:
- 您必须明确链接到它们;
- 由于它们直接链接到您的代码,它们必须使用完全相同的 C/C++ 运行时库,这意味着,至少在 Windows 上,分发静态库(不同的编译器、不同的编译器版本、不同的配置)是不切实际的同一个编译器使用不同的标准库,至少为这些方面的每个组合分发一个静态库是不切实际的);
- 因此,通常您必须首先在您自己的静态库版本上编译,然后才能链接到它.
- you have to explicitly link against them;
- since they are linked directly to your code, they have to use exactly your same C/C++ runtime library, which means that, at least on Windows, it's impractical to distribute static libraries (different compilers, different compiler versions, different configurations of the same compiler use different standard libraries, distributing a static library for every combination of these aspects would be impractical at least);
- because of this, in general you have to first compile on your own version of the static library, and only then link against it.
将所有这些与仅包含一个头文件进行比较... :)
Compare all this with just including a header file... :)
- 实际上,现代工具链可以识别这些存根并避免额外的间接步骤.有关详细信息,请参阅 Raymond Chen 的本系列.
相关文章