DLL ,是 Dynamic Link Library 的缩写,中文名
动态链接库
。DLL是一个包含可由多个程序,同时使用的代码和数据的库。 本文简介DLL 概念,记录 DLL 工程创建与使用方法。
简介 {#简介}
-
动态链接库( Dynamic-link library,缩写为 DLL) 是微软公司在windows 系统中实现共享函数库概念的一种实现方式。所谓动态链接,就是把常用的公共函数封装到 DLL 文件中,当程序需要用到这些函数时,系统才会动态地将 DLL 加载到内存中使用。
-
调用方式主要分为两种:
-
静态加载: 启动时加载DLL:需要使用
.h
头文件和.lib
文件 -
动态加载: 运行时加载DLL:使用
LoadBibrary()
GetProcessAddress()
-
-
动态链接库的扩展名:
.dll
,.ocx
或者.drv
(驱动程序)。
动态链接库的优势 {#动态链接库的优势}
- 由于 DLL 可以在需要时加载,因此可以节约内存空间,提升运行效率;
- 更新 DLL 不需要重新编译链接整个程序,仅更换 DLL、lib 、头文件等文件即可。
调用方式 {#调用方式}
定义外部接口 {#定义外部接口}
- 不是所有 dll 中的函数都可以在装载后调用,需要向外开放的内容在声明时需要加前缀
__declspec(dllexport)
- 我看到的现象是如果需要动态加载的函数,还额外需要定义在
extern "C"
函数体中
静态加载 {#静态加载}
- 静态加载 dll 是在程序启动时加载,需要使用
.h
头文件和.lib
文件 - 在应用程序中引入 dll 的头文件声名接口,引入库 lib 文件,在程序目录中包含 dll 文件,即可将 dll 中向外开放的接口当作正常接口使用
动态加载 {#动态加载}
- 可以在程序运行过程中随时动态加载 dll 中为动态加载开放的函数
- 完整使用流程如下:
- 声明函数指针
typedef DWORD(*MYDEMOW)();
- 定义函数指针变量
MYDEMOW demo =
- 动态加载DLL到内存
hmo = LoadLibrary(_T("DLL2.dll"));
- 函数指针变量接收DLL中加载函数的地址
MYDEMOW demo= (MYDEMOW)GetProcAddress(hmo, "DEMOW")
- 调用函数指针
demo();
- 释放动态链接库
FreeLibrary(hmo);
动态链接库搜索顺序 {#动态链接库搜索顺序}
-
对于Windows,加载动态链接库时:
- 如果内存中已经有同module名的DLL,除非是DLL redirection或manifest,否则直接就用内存中这个DLL而不再搜索。
- 如果DLL名字属于当前Windows版本的Known DLL,则必须用Known DLL。清单见 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.
- 如果DLL有依赖DLL,操作系统按缺省标准规则根据module名字搜索依赖DLL。即使第一个DLL指定了全路径。
-
Windows Desktop应用程序的DLL标准搜索序:
- 应用程序所在目录;
- 系统目录。GetSystemDirectory函数返回该目录。
- 16比特系统目录;
- Windows目录。使用GetWindowsDirectory函数返回该目录。
- 当前(工作)目录;
- 环境变量PATH中列出的目录。
- 如果SafeDllSearchMode被禁止,则当前目录成为第二个被搜索的目录。
创建 DLL {#创建-DLL}
- 以 Visual Studio 2017 环境为例:
文件
->新建
->项目
->Visual C++
->Windows 桌面
->动态链接库
。- 我给项目起名
dll_demo
- 新建头文件
dll.h
,在其中声明外界调用的类和接口,我在这里设置了几种示例,用于静态、动态调用测试:
-
新建
dll.cpp
源文件,在其中完成对外类、接口的实现 -
在源文件开头需要引入
pch.h
加入
#include "pch.h"
, 否则会报错
- 我选择了 Debug x86 平台,生成解决方案
- 在项目文件夹可以看到生成的
dll
,lib
等文件
- 至此我们完成了
dll
的创建
加载使用 DLL {#加载使用-DLL}
- 在已经生成好
dll
、lib
、.h
后,我们就可以着手使用了 - 创建 Visual C++ 空项目,取名
dll_load
- 我们采用运用
dll
,lib
,.h
文件的方式调用 dll - 需要配置包含目录包含
dll.h
- 加入
lib
文件所在路径,作为库目录
- 添加
lib
文件作为依赖项
-
将
dll
文件拷贝到项目源文件夹用于静态加载 -
创建源文件,起名
load.cpp
-
加入调用
dll
代码,其中包含了静态、动态加载 dll 函数、类的简单示例,一些需要注意的点我写在注释里了
- 运行代码,看到调用
dll
得到的输出
错误记录 {#错误记录}
- 在头文件中未给类定义添加CREATEDELL_API_DU修饰时,cpp中类成员函数会出现以上错误。
参考资料 {#参考资料}
- https://baike.baidu.com/item/.dll/2133451?fr=aladdin
- https://blog.csdn.net/dou3516/article/details/124123127
- https://zh.wikipedia.org/wiki/动态链接库
- https://blog.csdn.net/qq_43615820/article/details/126895973
- https://www.cnblogs.com/zpchcbd/p/11900727.html
文章链接:
https://www.zywvvd.com/notes/coding/cpp/dll-proj/dll-proj/