DLL
DynamicLinkableLibrary,是实现共享函数库的一种方式
通常来说,动态链接库文件里面也包含了程序运行所需要的代码和数据。也就是说动态链接库文件也是可执行文件,但是它不能单独运行,动态链接库是给其他可执行文件提供函数的。
- 分类:
导入库
随着dll一起生成的就是导入库,里面不包含任何代码,只给链接器提供信息用于导出DLL中的函数
优点:
模块性,只需要调用,不需要关注实现
更新方便,只需要替换dll文件
节约内存,共用一份dll
缺点:
缺失dll,程序无法运行
对象库(静态库)
里面包含了所有的数据和代码,没有DLL文件
优点:
-
不依赖其他文件
只需要发布exe
缺点: -
exe文件大,占用内存
更新需要替换整个exe文件
-
导出方式
申明导出
extern “C” __declspec(dllexport) int fun(void);
模块定义导出
属性->链接器->输入->模块定义文件
EXPORTS
fun @1 NONAME表示符号导出 -
调用方式
隐式链接
包含头文件 #include “…\dll.h”
导入链接库 #pragma comment(lib,"…\dll.lib")
使用函数名调用函数
显式链接
Loadlibrary
GetProcAddress
FreeLibrary -
DllMain
//1 dll文件是给别人提供函数中,不会作为一个程序单独去运行,也就是没有什么第一行执行代码的这种概念。
//2 通常我们都不需要去理会DllMain,不会在里面写什么代码。
//3 DllMain会在 程序加载DLL
// 程序卸载DLL
// 线程被创建了
// 线程被卸载了
BOOL APIENTRY DllMain( HMODULE hModule, //当前模块句柄
DWORD ul_reason_for_call,//调用原因
LPVOID lpReserved//保留
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH://被进程加载 1
case DLL_THREAD_ATTACH://线程加载了 2
case DLL_THREAD_DETACH://线程卸载了 3
case DLL_PROCESS_DETACH://被进程卸载 0
break;
}
return TRUE;
}
系统是在什么时候调用DllMain函数的呢?静态链接时,或动态链接时调用LoadLibrary和FreeLibrary都会调用DllMain函数。DllMain的第二个参数fdwReason指明了系统调用Dll的原因,它可能是::
DLL_PROCESS_ATTACH、
DLL_PROCESS_DETACH、
DLL_THREAD_ATTACH、
DLL_THREAD_DETACH。
以下从这四种情况来分析系统何时调用了DllMain。
- 插件pulgins
什么是插件?
在原始程序上进行扩展。
如何找到插件?
应用程序指明一个目录作为插件目录。
插件是以什么形式存在的?
绝大部分插件都是使用动态链接库形式存在。再使用LoadLibary,GetProcAddress
虽然插件后缀不是dll,本质上是一个动态链接库
插件提供哪些功能?
需要使用程序的文档,导出指定的函数
在程序不同时刻调用插件中的函数(程序加载,菜单加载,程序结束)。