一. 静态库包括.lib和.h文件,在工程中使用静态库分为3步:
<1> 在工程中加入静态库,有两种方法:
**方法一:项目设置中引用.lib,project-> setting-> link-> object/library modules中添加.lib;(需要在tools/options设置正确的引用路径)
**方法二:在项目中直接加入lib,project-> add to project-> files,选择正确的.lib。
**方法三:pragma comment(lib, "##/##/mine.lib") ,路径名,系统会优先查找环境path
<2> 在工程中包括.h文件;(可能 需要在tools/options设置正确的引用路径)
<3> 在工程中使用静态库中的函数;
二. 动态链接库一般包括.lib(导入库),.h,.dll文件,使用动态库有两种情况:
A . 隐式链接:load-time dynamic linking
同使用静态库相似,分为三步:引用.lib导入库,包含头文件,使用导出函数;
此种方法的好处是:可以像使用静态库一样直接调用函数
缺点:程序启动时加载所有需要的DLL,延长启动时间,效率低。
B. 动态加载:run-time dynamic linking
直接使用LoadLibrary或LoadLibraryEx 加载所需的动态库(并不需要对应的头文件,和LIB),然后指定所需的导出函数,效率最高!,但前提需要对DLL库有比较详细的了解。
缺点:需要使用GetProcessAddress()得到函数指针,函数调用相对麻烦。
基本概念:
目标库(静态库):
扩展名.lib,静态连接,其代码会加入到可执行程序中。
动态库:
扩展名.dll,动态链接,发生在运行时。
输入库(导入库):
扩展名.lib,目标库的一种特殊形式。输入库不含代码,而是为链接程序提供信息,以便在.exe文件 中建立动态链接时要用到的重定位表。
输入库是动态库的辅助库,在vc中隐式导入动态库的时候用到该库,需要在引用该库的文件中包含该 库的头文件 ,并让连接程序能找到该输入库的位置(放在同一目录下或在vc中作相应的设置)。
目标库和输入库之用在程序的开发期间,动态库在运行期间使用。
一般来说,vb导入动态库时用显式导入(LoadLibrary),vc用隐式导入简单一些。
目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。
静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起。比如你链接一个静态库,如果其中有错,它会准确的找到是哪个obj有错,即静态lib只是壳子。
动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己LoadLibary调入DLL文件,然后再手工GetProcAddress获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。
导入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。
开源代码发布的惯用方式:
1. 预编译的开发包:包含一些.dll文件和一些.lib文件。其中这里的.lib就是导入库,而不要错以为是静态库。但是引入方式和静态库一样,要在链接路径上添加找到这些.lib的路径。而.dll则最好放到最后产生的应用程序exe执行文件相同的目录。这样运行时,就会自动调入动态链接库。
2. 用户自己编译: 下载的是源代码,按照readme自己编译。生成很可能也是.dll + .lib(导入库)的库文件
3. 如果你只有dll,并且你知道dll中函数的函数原型,那么你可以直接在自己程序中使用LoadLibary调入DLL文件,GetProcAddress
一些导入函数的介绍:
LoadLibrary
一般是动态加载DLL时(你并不需要对应的头文件,和LIB),显示加载dll中函数,前提是你自己对dll导出的函数参数很了解.
#pragma comment
一般是静态加载DLL时(对应的头文件、DLL,和LIB缺一不可,并且生产的EXE没有找到DLL文件就会导致“应用程序初始化失败”)
#import
导入的dll是com组建的dll,主要用来解析com组建内部结构,便与c++识别调用