DLL基础

DLL基础

编写一个简单的DLL

我们首先需要编写该DLL对应的头文件,该头文件可供可执行模块的代码使用,以便于可执行模块使用DLL中的函数和变量。

cpp 复制代码
//MyLib.h

#ifdef MYLIBAPI

#else

#define MYLIBAPI extern "C" __declspec(dllimport)

#endif

MYLIBAPI int g_nResult;
MYLIBAPI int Add(int nLeft, int nRight);

我们使用了MYLIBAPI来修饰头文件中声明的变量和函数。如果在包含该头文件之前没有定义MYLIBAPI宏,那么该宏修饰的变量和函数说明这些对象是在别处定义的,需要导入才可以使用。

再来看看DLL对应的CPP文件:

cpp 复制代码
//MyLib.cpp

#include <Windows.h>

#define MYLIBAPI extern "C" __declspec(dllexport)

#include "MyLib.h"

int g_nResult;

int Add(int nLeft, int nRight)
{
	g_nResult = nLeft + nRight;

	return g_nResult;
}

我们可以看到,在包含MyLib.h头文件之前,定义了MYLIBAPI宏,此时该宏修饰的对象是对外导出使用的。

两分代码中的extern "C"是为了避免C++编译器对函数名和变量名进行改编。

接下来使用如下命令生成DLL:

shell 复制代码
cl /c .\MyLib.cpp
link /DLL .\MyLib.obj

使用/DLL说明该obj文件应该被当作一个DLL生成,链接器会在DLL文件中保存一些与可执行文件不同的信息,这样加载程序就能够将该文件映像识别为DLL而不是应用程序。

生成的DLL中包含了一张导出表,表中列出了DLL导出的变量和函数的RVA。

上述命令除了生成DLL文件之外,还生成了一个同名的.lib文件。如果链接器检测到DLL中导出了至少一个函数或变量,就会生成这个lib文件。这个文件列出了DLL中所有被导出的函数和变量符号名。这个文件对于生成最终的可执行文件是必须的,稍后我们可以看到如何使用它。

编写测试程序

我们来使用一下上一节写的DLL。

cpp 复制代码
#include <Windows.h>
#include <strsafe.h>
#include <stdlib.h>

#include "MyLib.h"

int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPTSTR, _In_ int)
{
	int nLeft = 10, nRight = 25;

	TCHAR sz[100];
	StringCchPrintf(sz, _countof(sz), TEXT("%d + %d = %d"), nLeft, nRight,
			Add(nLeft, nRight));

	MessageBox(NULL, sz, TEXT("Last Result"), MB_OK);

	StringCchPrintf(sz, _countof(sz), TEXT("The result from last Add is: %d"), g_nResult);
	MessageBox(NULL, sz, TEXT("Last Result"), MB_OK);

	return(0);
}

我们使用如下命令生成可执行文件:

shell 复制代码
cl /D_WINDOWS .\MyExeFile1.cpp
link /SUBSYSTEM:WINDOWS .\MyExeFile1.obj user32.lib .\MyLib.lib

编译生成的obj文件中包含一个导入段,这里列出了该文件需要的所有DLL的名称,以及所引用的每个DLL中的变量和函数名称。加载程序会解析这个段,并将所需的DLL映射到该程序的进程地址空间之中。

程序运行

可执行文件的导入段中只有所需DLL的名称,并不包含其具体路径,加载程序会按照一定的顺序检索磁盘中的路径来寻找DLL。在找到所需的DLL后,加载程序会将其加载到进程的地址空间中,根据导出段的RVA和DLL在进程地址中加载的基址生成一个地址,利用该地址对可执行文件的导入段进行修改。

至此动态链接就完成了。这里介绍的是隐式载入时链接,这是最常用的链接。

相关推荐
板栗栗-72 个月前
玩游戏/用设计软件提示d3dcompiler_47.dll缺失怎么修复?5步快速定位问题,高效修复不踩坑
dll·dll修复·dll错误·dll缺失·dll解决工具
板栗栗-73 个月前
从根源破解“找不到 vcruntime140.dll 无法执行”问题:原因分析、安全修复工具推荐及预防指南
安全·dll·dll修复工具·dll修复·dll错误
板栗栗-73 个月前
设计软件启动失败?“找不到vcruntime140.dll,无法继续执行代码” 场景化解决方案来了
dll·dll修复·dll错误·dll缺失·dll解决工具
板栗栗-73 个月前
笔记本电脑频繁出现 vcomp140.dll丢失怎么办?结合移动设备特性,提供适配性强的修复方案
电脑·dll·dll修复工具·dll修复·dll错误·dll解决工具
板栗栗-74 个月前
频繁提示vcomp140.dll丢失怎么办?从文件作用到修复细节,7步搞定所有相关问题
dll·dll修复·dll错误·dll缺失·dll解决工具
许野平4 个月前
Rust:如何开发32位的DLL动态库
windows·rust·动态库·dll·32位
许野平4 个月前
Rust:如何开发Windows 动态链接库 DLL
windows·单片机·rust·dll·动态链接库
许野平4 个月前
Rust:开发 DLL 动态链接库时如何处理 C 字符串
c语言·开发语言·rust·字符串·动态库·dll
板栗栗-75 个月前
Windows系统提示“mfc140u.dll丢失”?详细修复指南,一键恢复程序运行!
windows·dll·dll修复·dll错误·dll缺失