静态库:
在链接的时候,链接器将目标文件(.obj)和用到的静态库一起打包到最后生成的可执行文件中。因此,使用了静态库的可执行程序存储在磁盘上的空间就比较大。Windows上的静态库是.lib文件(但和dll文件的.lib文件是不同的,下面会有阐述)。
动态库:
在可执行程序被加载到内存中执行的时候,才会去加载动态库。Widows上的动态库是dll文件(Dynamic Linked Library)。
静态库与动态库的区别:
1. 使用了静态库的程序存储在磁盘上的空间比使用了动态库的程序要多。
2. 使用了动态库的程序,若有多个副本在内存中执行,又或者是不同的程序但都使用了同一个动态库,则它们所调用的动态库在内存中只有一份,所以很节省内存空间;而使用了静态库的程序的多个副本在内存中时,它们所使用的库所占的内存也是多份,因此浪费空间。
3. 在库需要升级的时候,使用动态库的程序只需要升级动态库就好(假设接口不变),而使用了静态库的程序则需要升级整个程序。
在Windows操作系统中,Visual Studio使用lib.exe作为库的管理工具,负责创建静态库和动态库。
Window与Linux执行文件格式不同,在创建动态库的时候有一些差异:
2. 然后,使用库管理器 Lib.exe 链接代码 (lib StaticMath.obj),创建静态库StaticMath.lib。
使用静态库有2个方法:
在 Project’s Properties -> Linker -> Input ->Additional Dependencies,添加静态库的文件名。
注意,静态库的文件名叫xxx.lib,和动态库的导入库文件的文件后缀名相同。二者内容当然是完全不同的:静态库文件当然包含了执行代码和符号表,而动态库的导入库文件则只包含了地址符号表。
先来看看它们的作用:
1. __declspec(dllexport)可以被用来修饰一个函数或一个类,以表明这是一个导出函数或导出类。所以,这个宏是用在为dll做编程实现的时候的。
当修饰类的时候,该宏要写在class关键字的后面、类名的前面;
当修饰函数的时候,要写在函数声明的前面,而因为name mangling的问题,在此宏的前面还要写上extern“C”. 比如:
3. 从以上可以看出,在dll的实现中,我们需要__declspec(dllexport)来表明这些函数和类是导出函数和导出类,而在使用dll的程序中,又要用__declspec(dllimport)来表明它所描述的函数或类是来自于某dll。那么这样的话,岂不是需要2个不同但又很相近的头文件来做这些函数和类的声明了吗?能否将这2个函数合并成一个呢?答案是可以的 – 使用宏进行判断:当宏A存在时,就认为宏B是__declspec(dllexport),否则就认为宏B是__declspec(dllimport)。具体实例如下:
所以,在dll的实现中,需要在Preprocessor Definitions里定义MYDLL_EXPORTS,而在dll的使用者那里就不需要定义MYDLL_EXPORTS了。
在 Project’s Properties -> Linker-> General -> Additional Library Directories,添加动态库的导入库文件(即.lib文件)的所在目录;
在Project’s Properties -> Linker -> Input ->Additional Dependencies,添加动态库的导入库的文件名。
隐式调用的优点是,既可以使用导出函数,也可以使用导出类。
a. 调用 LoadLibrary(或相似的函数)以加载 DLL 和获取模块句柄。
b. 调用 GetProcAddress,以获取指向应用程序要调用的每个导出函数的函数指针。由于应用程序是通过指针调用 DLL的函数,编译器不生成外部引用,故无需与导入库链接。
c. 使用完 DLL 后调用 FreeLibrary。
显式调用有一个比较大的问题,就是很难使用导出类。很难并不是不可以,可以用专业工具修改.def并将类也声明为extern“C”的方式来做到,但是是不推荐这样做的。具体文献可以参考这里:
http://www.cppblog.com/codejie/archive/2009/09/24/97141.html
http://blog.csdn.net/denny_233/article/details/
其实,搜索动态库文件dll的顺序是这样的:
1. 包含EXE文件的目录,
2. 进程的当前工作目录,
3. Windows系统目录,
4. Windows目录,
5. 列在Path环境变量中的一系列目录。
首先,我们来创建一个动态库,叫做MyDll.dll. 这首选需要在VS下创建一个dll的工程,具体过程就不赘述了。总共只需要2个文件,MyDll.h 和 MyDll.cpp,详细代码如下:
MyDll.h如下:
MyDll.cpp如下:
这个dll工程build后,就可以生成MyDll.dll和MyDll.lib了。但是要注意,在Preprocessor Definitions中要记得添加上MYDLL_EXPORTS宏。否则就没啥导出的了。
然后,再建一个Windows Console工程,里面只需要一个cpp文件:
此文件中使用了2种方法来调用MyDll.dll,即隐式调用和显式调用。最后将第二个工程设置为Startup工程,build后再按Ctrl + F5,就可以看到执行结果了。
到此这篇动态库和静态库的区别(动态库和静态库的区别和联系)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/bcyy/34371.html