头文件和库文件-静态库和动态库

一、头文件和库文件  

  头文件中有函数的申明,库文件实现函数的定义。对于头文件和库的区别我们可以这样理解:就是头文件提供的是一个函数的声明,并没有这个函数具体代码,而库就是存放这个函数的具体实现代码。

  头文件的主要作用在于多个代码文件全局变量(函数)的重用、防止定义的冲突,对各个被调用函数给出一个描述,其本身不需要包含程序的逻辑实现代码,它只起描述性作用,用户程序只需要按照头文件中的接口声明来调用相关函数或变量,链接器会从库中寻找相应的实际定义代码。

  比如,printf函数。使用时应包括stdio.h,打开stdio.h你只能看到,printf这个函数的申明,却看不到printf具体是怎么实现的,而函数的实现在相应的C库中。而库文件一般是以二进制形式而不是C源文件形式提供给用户使用的。程序中包括了stdio.h这个头文件。链接器就能根据头件中的信息找到printf这个函数的实现并链接进这个程序代码段里。总结起来就是,库文件通过头文件向外导出接口。用户通过头文件找到库文件中

  函数实现的代码从而把这段代码链接到用户程序中去。c语言在编译过程中会经过预处理(需要头文件) -> 编译 -> 汇编 -> 链接(需要库文件); 执行时可能还有动态链接过程。执行的时候可能还有动态链接过程。在编译的时候只要有头文件的声明就可以了,在链接的时候,把已经编译好的.obj和现有的.lib文件进行链接,这时就可以最终生成可执行文件了。

  其实头文件与其实现文件或相应lib文件都没有直接的联系。头文件是告诉编译器函数是如何去调用如何返回的,所有实现都是分别编译,最后在链接阶段链在一起。头文件包含声明,库文件包含实现或者与动态库的连接 。所以如果在代码里要用到这些函数那么就要包含头文件,编译的时候才能知道这些函数的原形,在进行代码连接的时候就需要库文件了,这时连接器就把函数的实现代码(静态库)连接到你的程序或者将你的函数调用连接到相应的动态库中对应函数, lib是静态库,编译的时候代码直接插入到你的程序 ,编译的时候,只是产生一些调用动态库内代码的导入表,真正运行的时候是调用的动态库内的代码

 

二、.h(头文件) .lib(库文件) .dll(动态链接库文件) 关系

  .h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的

  附加依赖项的是.lib不是.dll,若生成了DLL,则肯定也生成 LIB文件。如果要完成源代码的编译和链接,有头文件和lib就够了。如果也使动态连接的程序运行起来,有dll就够了(放在Debug文件夹里)。在开发和调试阶段,当然最好都有。

.h .lib .dll三者的关系是:

  • H文件作用是:声明函数接口
  • DLL文件作用是: 函数可执行代码

  当我们在自己的程序中引用了一个H文件里的函数,编链器怎么知道该调用哪个DLL文件呢?这就是LIB文件的作用: 告诉链接器 调用的函数在哪个DLL中,函数执行代码在DLL中的什么位置,这也就是为什么需要附加依赖项 .LIB文件,它起到桥梁的作用。如果生成静态库文件,则没有DLL ,只有lib,这时函数可执行代码部分也在lib文件中

  目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive(存档),即合并到一起。比如你链接一个静态库,如果其中有错,它会准确的找到是哪个obj有错,即静态lib只是壳子。动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己LoadLibary调入DLL文件,然后再手工GetProcAddress获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。导入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息

  一般的动态库程序有lib文件和dll文件。lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的如果有dll文件,那么对应的lib文件一般是一些索引信息具体的实现在dll文件中如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。静态编译的lib文件有好处:给用户安装时就不需要再挂动态库了。但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。在动态库的情况下,有两个文件,而一个是引入库(.LIB)文件,一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据应用程序使用LIB文件链接到所需要使用的DLL文件库中的函数和数据并不复制到可执行文件中因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误

-------------------------------------------------------------------------------------
静态链接库(Lib)与动态链接库(DLL)的区别 
  ①静态连接库就是把(lib)文件中用到的函数代码直接链接进目标程序,程序运行的时候不再需要其它的库文件;动态链接就是把调用的函数所在文件模块(DLL)和调用函数在文件中的位置等信息链接进目标程序,程序运行的时候再从DLL中寻找相应函数代码,因此需要相应DLL文件的支持
  ②静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。

每一个lib文件就是若干函数(假设只有函数)的定义” 
  lib库有两种,一种是包含了函数所在DLL文件和文件中函数位置的信息,称为导出库;一种是包含函数代码本身,一般现有的DLL,用的是前一种库;以前在DOS下的TC/BC等,是后一种库。包含函数原型声明的,是头文件(.h)。 

“通过#include包含这些函数声明的头文件后,我们的应用程序就可以使用lib文件中的函数”
  还要指定编译器链接相应的库文件。在IDE环境下,一般是一次指定所有用到的库文件,编译器自己寻找每个模块需要的库;在命令行编译环境下,需要指定每个模块调用的库。 

“那他和直接给出那个函数定义的文件,比如.cpp文件,和头文件有什么区别,静态链接库有什么用” 
  cpp文件是源代码,库文件是编译后的二进制代码,比如你可以调用Windows的API,但是不能看到其源代码一样。 

“静态链接库中的lib文件只要用到,则整个lib文件的内容都放进了exe文件中,那它是被编译进去还是链接的时候连接进去的呢?” 
  是在链接的时候将lib链接到目标代码中。

 

三、静态链接库(Lib)建立

详见:.h(头文件) .lib(库文件) .dll(动态链接库文件) 之间的关系和作用的区分

 

四、总结

①.h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的。

②若生成了DLL,则肯定也生成 LIB文件。如果要完成源代码的编译和链接,有头文件和lib就够了。如果也使动态连接的程序运行起来,有dll就够了(放在Debug文件夹里)。

③.h .lib .dll三者的关系是:H文件作用是:声明函数接口;DLL文件作用是: 函数可执行代码。

④LIB文件的作用: 告诉链接器调用的函数在哪个DLL中,函数执行代码在DLL中的什么位置,它起到桥梁的作用。如果生成静态库文件,则没有DLL ,只有lib,这时函数可执行代码部分也在lib文件中。

  静态库(lib) 动态库(dll)
简介
  • 静态链接库(Static Libary,简称“静态库”)                          
  • 动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)
组成
  • 静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起,静态lib只是壳子。
  • 静态库只有lib文件,索引和实现都在其中。
  • 动态库一般会有对应的导入库,方便程序静态载入动态链接库
  • 一般的动态库程序有lib文件和dll文件。lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。
作用
  • lib是链接时需要的
  • dll是运行时需要的 
区别
  • 静态库本身就包含了实际执行代码、符号表等等 。
  • 静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中
  • 静态链接库中不能再包含其他的动态链接库或者静态库
  • 动态库有两个文件:引入库(.LIB)文件和DLL文件。引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。
  • DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。
  • 动态链接库中还可以再包含其他的动态或静态链接库
posted @ 2019-02-25 10:40  骏骏  阅读(6491)  评论(0编辑  收藏  举报