静态链接库和动态链接库

以前的时候写过这方面的博客,当时写的时候都觉得已经懂了。今天闲着没事干,和咚哥他们去大华校招笔试遇到了这个问题。我突然间发现SDK没写三个月,把Dll都忘记了。回来看了下,复习下。

以前写过程序的装载和链接的博客,那是OS上面比较理论的。实际用函数库的时候主要分为,静态库和动态库,这里就简简单单地介绍下了。

静态库


静态库(Static Libary)就是平时的 .lib 文件,静态库里面包含的是所有的代码和数据,是完整的!程序在编译生成.obj文件后,连接器将.obj文件和.lib文件整合到.exe里面,程序运行时候所需的函数代码和数据都已经在.exe中了,静态库很霸道,不管你愿不愿意,它就一股脑儿把所有需要的东西都给你,所以就没有导出函数这个概念,缺点就是整合出来的产品比较大,而且很不利于下次的升级,每次升级都得把lib文件修改,然后重新编译链接整合出来新的程序,而且静态链接库不能包含其他的链接库,这一点和动态链接库有很大的区别

使用方式:


在生成的.h文件中做如下声明

extern "C" function()......

在调用函数的.cpp文件里面

#include "XXX.h"

#pragma comment(lib,"XXX.lib")

动态链接库


动态链接库是在运行的时候动态加载的,可以人为也可以非人为,看你怎么用,总之就是很灵活。下面直接说调用方式。

1.隐式加载


隐式加载把你的动态链接库的代码生成.lib文件+.dll,隐式加载的时候需要的就是.h,.dll,.lib文件。说的简单点,.dll文件里面是函数的定义和数据,只是一部分,那么声明呢?声明就在.lib,.lib文件就包含了.dll文件中函数的声明和一些其他的数据。奇怪了,为什么上面的静态链接库里面的.lib文件不是涵盖了所有的函数信息吗?我以前百思不得其解,查了下网上的资料,此.lib非彼.lib。若是编译链接你的dll至少输出一个函数的话,.lib文件就当作一种引导函数的输出表来用了,里面包含了函数的“声明”。在隐式加载里面的.lib文件编译链接的时候整合到程序里面,但是dll里面的代码和数据却没有整合进去,让exe文件所占空间更小。但是加载程序加载exe,dll就被加载到内存中了,加载程序先为新的进程创建一个虚拟地址空间,并将可执行模块映射到新进程的地址空间中。加载程序接着解析可执行模块的导入段。对导入段中列出的每个DLL,加载程序会在用户的系统中对该DLL模块进行定位(差不多就是和lib中进行核实),并将该DLL映射到进程的地址空间中。注意,由于DLL模块可以从其它DLL模块中导入函数和变量,因此DLL模块可能有自己的导入段并需要将它所需的DLL模块映射到进程的地址空间中。

详细参考http://www.cnblogs.com/forlina/archive/2011/08/08/2131011.html

隐式加载使用方式:


#include "XXX.h"

#pragma comment(lib,XXX.lib)

并把dll放到环境变量或者执行目录下

2.显示加载


采用LoadLibrary,FreeLibrary来手动加载,这种加载是在程序运行的时候加载所需要的Dll,和隐式链接不一样,显示加载随时可以在需要的时候加载指定的Dll模块,也可以随时卸载。而隐式加载实际上存在一个Dll计数器,当计数器为0的时候系统就自动帮你卸载了。函数会在用户的系统中对DLL的文件映像进行定位,并试图将该文件映像映射到调用进程的地址空间中。LoadLibrary返回的HMODULE表示文件映像被映 射到的虚拟内存地址。  

显示加载使用方式:


只需要Dll即可

详细参考http://www.cnblogs.com/forlina/archive/2011/08/08/2131042.html

 

 

标签:SDK, Windows

评论已关闭