动态链接库(DLL)和静态链接库(LIB)

最近使用一些第三方库,感觉以前使用的不太明白,正好有机会好好整理一下

链接库有:静态链接库(static libary),动态连接库(dynamic-link library,DLL)及DLL的导入库(import library)。
1、静态链接库,在静态库中,函数和数据被编译进一个二进制文件(通常扩展名为*.lib),Visual C++的编译器在链接过程中将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件,这个过程称为"静态链接",库中的 代码最后需要连接到你的可执行文件中去,所以静态连接的可执行文件一般比较大一些。由于静态库已经链接到可执行文件中,因此不用单独发布。

2、动态链接库 (DLL) 是作为共享函数库的可执行文件。 动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。 DLL 还有助于共享数据和资源。 多个应用程序可同时访问内存中单个 DLL 副本的内容。动态链接与静态链接的不同之处在于:动态链接允许可执行模块(.dll 文件或 .exe 文件)仅包含在运行时定位 DLL 函数的可执行代码所需的信息。 在静态链接中,链接器从静态链接库获取所有被引用的函数,并将库同代码一起放到可执行文件中。
使用动态链接代替静态链接有若干优点。 DLL 节省内存,减少交换操作,节省磁盘空间,更易于升级,提供售后支持,提供扩展 MFC 库类的机制,支持多语言程序,并使国际版本的创建轻松完成。(from MSDN)

导入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和 数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,当程序运行时再把程序 代码和被调用的函数代码链接起来,从而节省了内存资源。很多数情况下,不需要使用 LIB 创建导入库。 在链接包含导出的程序(可执行文件或 DLL)时,LINK 自动创建描述导出的导入库。


静态链接库lib中,一个lib文件实际上是任意个obj文件的集合,obj文件是cpp文件编译生成的。
在Visual Studio中新建一个static library类型的工程,添加自定义头文件和源文件,然后编译,就生成了XXX.lib文件。
其他的程序要使用静态链接库lib有两种方式:
1.在project->properties->C++->General 中 Additional Include Directories 中添加该静态库头文件所在目录
2.在project->properties->link->general中 Additional Library Directories,添加.lib所在的目录
3.在project->link->input中 Additional Dependencies加入.lib文件
4.使用时添加相应的头文件.h
另一种方法就是直接在源代码中加入#pragma comment(lib, "/path/to/lib/XXX.lib")。

动态链接库(DLL)使用需要三个文件(.lib非必须):.h头文件,各个类或函数的声明,当应用程序调用.dll时,需要将该文件包含入应用程序的源文件中。
.lib文件,是dll在编译、链接成功之后生成的文件,与静态连接库不同,其中没有实际的实现,它只是提供动态链接到DLL所需要的信息,当其他应用程 序调用dll时,需要将该文件引入应用程序,否则产生错误。很多情况下,不需要使用导入库,可以使用LoadLibrary(或类似函数)加载载。
.dll文件,具体实现,开应用程序在发布时,需要有.exe文件和.dll文件。
要在Visual Studio中使用dll:
1.在project->properties->C++->General 中 Additional Include Directories 中添加该动态链接库头文件所在目录
2.在project->properties->link->general中 Additional Library Directories,添加.lib所在的目录
3.在project->link->input中 Additional Dependencies加入.lib文件
4.使用时添加相应的头文件.h
5.生成应用程序后,把所需要的DLL文件复制到程序所在目录下。

确定要使用的链接方法:显示连接和隐式链接(参见msdn)
确定要使用的链接方法:https://msdn.microsoft.com/zh-cn/library/253b8k2c.aspx
隐式链接:https://msdn.microsoft.com/zh-cn/library/d14wsce5.aspx
显示链接:https://msdn.microsoft.com/zh-cn/library/784bt7z7.aspx

链接库使用时常见问题
1.连接时提示one or more multiply defined symbols found
可能原因:编译选项不一致,
解决方法:查看project->property->C++->Code Gernation-> Runtime Library,比如当前project的编译选项(/MDd),而lib库的编译选项是(/MD)则有可能出现这种情况,还有就是当前project使 用的是Debug模式,对应的库亦应该使用Debug模式编译出的库

2.连接时提示**** 重定义
可能原因:当前链接库与系统链接库或其他链接库冲突
解决方法:使用#undef 将重定义的函数取消定义

参考:

Visual C++ 中的 DLL:https://msdn.microsoft.com/zh-cn/library/1ez7dh12.aspx