在进行Windows时,经常会碰到调用函数库的情况,函数库也极大的扩展了编程的模块化能力。别人写好了函数,放到某个地方(函数库),告诉你使用方法,你来调用就可以完成你想做的事情,这简直太方便了。
在实际编程中,我们经常会碰到两种函数库德使用方法,静态的和动态的,在编译时,直接将函数代码加入到程序中,由程序来进行编译;另一种是直接编译出链接库,Lib中包含了DLL文件和函数入口信息,这些函数在程序运行时,被动态的加载到程序的进程空间中。
换句话说,静态库你是把它引入你的程序代码中,你最终编译出来可执行的程序实际上是你的代码+函数库的代码;动态库是你只在程序代码中调用函数库,也就是说动态函数库和你的程序代码不直接耦合,只有你的程序调用时,操作系统的执行环境会帮你找到那个动态库,并根据你给出的函数入口信息,找到相应的函数,加载到进程空间中,供你的程序使用。
Lib和Dll,很容易让人混淆,主要是历史原因。早期是Lib是只有静态应用的,简单来说,生成的Lib库,你必须加载到你的代码中,它跟你的代码一起编译,最后产生一个应用程序。后来因为各种通用的库原来越大,越来越多,导致编程时可以引用很多库,那么最终的结果是应用程序越来越大,逐渐就产生了一种动态调用的方法,就是Lib中只是包含函数的一些索引信息,记录函数的入口位置啊这些东西,而函数是在用时才调,函数被编译成Dll文件,可以有操作系统的执行环境进行加载。当然动态库,因为它灵活的原因,逐渐有了很多其他的用法,这个略过。
使用静态lib的方法:
静态lib中,一个lib文件实际上是任意个obj文件的集合,obj文件是cpp文件编译生成的。
其他应用程序如果要使用这个lib文件,很简单,include那个头文件,把lib加入到工程lib目录中就好
使用动态DLL的方法:
在动态Dll中,它的lib只有函数的入口信息,使用方法一般分为隐式和显示调用两种。
(1)隐式调用
隐式调用,其使用方法和静态lib的调用类似,只是应用程序编译时不会引入调用函数的代码,具体函数还是在调用时,动态加载。
通过project->link->Object/Library Module中加入.lib文件(或者在源代码中加入指令#pragma comment(lib, “Lib.lib”)),并将.dll文件置入工程所在目录,然后添加对应的.h头文件。
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0ac3a2d53663ec01c7f7225264eeefae.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
(2)显式调用
显示的意思就是真的把库动态的调用,具体操作就是使用函数指针和WIN32 API函数LoadLibrary、GetProcAddress装载,这个是用方法很动态,只要有Dll就行,当然你的调用一定要符合函数的调用规范。先加载动态库,然后找到函数,调用之。如果你的Dll做的很open,那么其他程序开发者也可以调用你的Dll中。现实中,很多专业公司会开放一些函数库,有静态的当然也有动态的。显示调用如下:
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/2f88ce130b654eb5dc6788e02dbcfc90.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f70a0fde2b51b7dd92a70e712e540cf6.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4a5daaec04350a363f186a4d2c5ed6ce.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/df37983f39daa189b8c814e01a6a9011.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0ac3a2d53663ec01c7f7225264eeefae.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cbef093dcc044b2793832001e2365e43.gif)
LoadLibrary函数利用一个名称作为参数,获得DLL的实例(HINSTANCE类型是实例的句柄),通常调用该函数后需要查看一下函数返回是否成功,如果不成功则返回NULL(句柄无效),此时调用函数FreeLibrary释放DLL获得的内存。
GetProcAddress函数利用DLL的句柄和函数的名称作为参数,返回相应的函数指针,同时必须使用强转;判断函数指针是否为NULL,如果是则调用函数FreeLibrary释放DLL获得的内存。此后,可以使用函数指针来调用实际的函数。
最后要记得使用FreeLibrary函数释放内存。