库文件是计算机上的一类文件,提供给使用者一些开箱即用的变量、函数或类。库文件_百度百科

库的存在,就是为了代码的复用,同时减少项目结构的冗杂。

在项目编译过程中,执行到”汇编”阶段之后,项目从汇编语言变成了只有机器可以读懂的二进制机器指令,然后再执行”链接”。库文件就是一类二进制指令组成的文件,在”链接”的阶段被添加到项目中参与编译,最后生成可执行文件。

一个完整的库包括头文件、库文件。

image-20241125171020325

库文件是通过.cpp源文件生成的,将源文件中的【某些内容】构建成了二进制指令,保存在了库文件中。

【某些内容】:用户有时候可以指定哪些类或函数构建到库文件中,而不是将源文件中全部的内容都导入到库文件中。这些被选择导入库文件中的,就成为导出类、导出函数、导出变量。通过为这些类、函数、变量设置”导出符号“,将它们标定成为导出类、函数和变量。

用户在使用库的时候,通过引入库中的头文件,来调用库中的类和方法。因为库文件内容全部都是二进制指令,用户无法读懂,所以必须要借助头文件,才能被用户所使用,此时头文件就像是一本说明书,告知了用户库中包含的类和方法,以及这些东西的作用。
同时,头文件中的声明,也告知了编辑器这些内容是存在的,只不过实现是在其他的地方,编辑器在预处理阶段,就不会因找不到库中内容的声明而报错了。

img
将库导入项目中的过程

库文件分为静态库和动态库:

  • 静态库:在程序的链接阶段被复制到了程序中。
  • 动态库:在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。
    • 使用动态库系统只需载入一次,不同的程序可以得到内存中相同的动态库的副本,因此节省了很多内存,而且使用动态库也便于模块化更新程序。
    • 在操作系统中,许多应用程序并不是只有一个完整的可执行文件,大多数程序模块被分割成一些相对独立的动态库。当我们执行某一个程序时,相应的动态库文件就会被调用。一个应用程序可使用多个动态库文件,一个动态库文件也可能被不同的应用程序使用,这样的动态库文件被称为共享库文件。

库文件的后缀

Linux

  • 静态库:.a

  • 动态库:.so (shared object)

Windows

  • 静态库:
    • MSVC:.lib
    • MinGW:.a
  • 动态库:
    • MSVC:.dll.lib
    • MinGW:.dll.dll.a

在使用不同的编译器生成动态库时,MSVC(Microsoft Visual C++)和MinGW(Minimalist GNU for Windows)会有不同的输出文件,这主要是由于它们使用不同的工具链和库管理方式。

  1. MSVC生成的是.lib和.dll

    • MSVC使用的是Microsoft的C/C++标准库格式,这些库文件通常以.lib为扩展名。这个.lib文件实际上是一个导入库(Import Library),它包含了函数的描述和在DLL中的位置,用于在编译时期链接到DLL中的符号。MSVC生成的DLL文件包含了实际的代码和数据,用于运行时被加载到应用程序中。
  2. MinGW生成的是.dll.a和.dll

    • MinGW使用的是GNU工具链,因此它通常使用与GNU标准库兼容的库文件格式。这些库文件具有以.a为扩展名的静态库和以.dll为扩展名的动态链接库。MinGW下的.dll.a文件是动态库的导入库,类似于MSVC下的.lib文件,它提供了编译链接过程中所需的符号和接口信息。
    • 值得注意的是,MinGW下的.dll文件自身也可以参与编译链接过程,而MSVC下生成的.dll文件并没有此功能。

总结来说,MSVC和MinGW在生成动态库时产生的文件差异,主要是由于它们遵循不同的库管理和链接机制。MSVC遵循Microsoft的标准,生成.lib作为导入库,而MinGW遵循GNU的标准,生成.dll.a作为导入库。这两种方式虽然在文件扩展名上不同,但功能上是相似的,都是为了在编译时期提供必要的符号链接信息,以便应用程序能够正确地链接到动态库中的函数。