静态链接库与动态链接库不同在于
一、两种链接库
1、静态链接库:
这种库包含函数代码本身,即声明和实现的代码都有。在编译时直接将代码加入程序当中。这个lib文件是静态编译出来的,只有.lib文件(相当于是n个.obj文件的集合,obj文件由一个个cpp文件编译得到),如下图所示,索引和实现都在其中。静态编译的lib文件有好处:给用户安装时就不需要再挂动态库了。但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。 创建静态链接库请参见(代码自己打一下,不然会报错):http://hi.baidu.com/schsun/item/fafcd31b528716c539cb308d
2、动态链接库:
这种库包含了一个.lib文件(引用库文件,这里相当于头文件)和一个.dll文件(dll文件,相当于cpp文件)。其中,引入库文件包含函数位置的信息(入口),而DLL文件是函数具体实现。引入库文件包含被DLL库导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。
如何建立动态链接库请参考:http://blog.csdn.net/zddblog/article/details/7352917#
二、两种链接方式:
静态链接:使用静态链接库,链接器从静态链接库LIB获取所有被引用函数,并将库同代码一起放到可执行文件中。
动态链接:使用动态链接库,允许可执行模块(.dll文件或.exe文件)仅仅包含DLL文件中的函数内存地址,在程序运行时的加载
函数代码。
三、使用两种库
1、使用静态库需注意两个文件:(将要被我们引用的使用的库文件是1.lib)
(1).h头文件,包含.lib文件中说明输出的类或符号原型或数据结构。应用程序调用lib时,需要将该文件包含入应用程序的源文件中。
步骤1、在项目->属性->VC++目录->包含目录 里面加入相应的.h的所在目录的路径
步骤2、源文件中加一句话:#include".....h"
(2).LIB文件。
方法一: 项目->属性->VC++目录->库目录中添加1.lib的路径;在项目->属性->链接器->输入中添加1.lib
方法二:可以在源代码中加入一行指令即可:#pragma comment(lib,"C:\\Users\\Administrator\\Documents\\visual studio 2010\\Projects\\1\\Debug\\1.lib")
2、使用dll需注意三个文件:
(1).h头文件,包含dll中说明输出的类或符号原型或数据结构的.h文件。应用程序调用dll时,需要将该文件包含入应用程序的源文件中。
(2).LIB文件,是dll在编译、链接成功之后生成的文件,作用是当其他应用程序调用dll时,需要将该文件引入应用程序,否则产生错误。
(3).dll文件,真正的可执行文件,开发成功后的应用程序在发布时,只需要有.exe文件和.dll文件,并不需要.lib文件和.h头文件。
四、搜索路径顺序
动态库搜索路径:
- 包含可执行文件的目录
-
Windows的系统目录 (该目录可通过GetSystemDirectory得到)
- 16位的系统目录 (即Windows目录下的system子目录)
-
Windows 目录 (该目录可通过GetWindowsDirectory得到)
- 进行的当前工作目录
- PATH环境变量中所列出的目录
四、编译链接过程
事实上图中的.lib文件也相当于若干个.obj文件.
总结一下,整个编译链接的过程如下:
1,程序员写好.h文件和.cpp文件;
2,编译器对源文件进行预处理,主要包括一下
指令 用途
# 空指令,无任何效果
#include 包含一个源代码文件
#define 定义宏
#undef 取消已定义的宏
#if 如果给定条件为真,则编译下面代码
#ifdef 如果宏已经定义,则编译下面代码
#ifndef 如果宏没有定义,则编译下面代码
#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码,其实就是else if的简写
#endif 结束一个#if……#else条件编译块
#error 停止编译并显示错误信息3、每个.cpp文件单独编译,生成若干个.obj文件
4、编译器链接所有生成的obj文件和必要的.lib文件(相当于若干个.obj文件),生成可执行文件.exe