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在进程地址中加载的基址生成一个地址,利用该地址对可执行文件的导入段进行修改。

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

相关推荐
qq_3692243310 天前
Windows全系通用!ntdll.dll文件丢失、报错、闪退问题的完整排查与修复教程
windows·dll·dll修复·dll丢失·dll错误
qq_3692243312 天前
由于找不到vcruntime140_1.dll无法启动游戏?游戏闪退、启动失败专属修复方法
游戏·dll·dll修复·dll丢失·dll错误
雾沉川14 天前
Visual C++ 运行库合集 v105.0 部署与故障排查技术指南
开发语言·c++·dll
qq_3692243321 天前
电脑提示xinput1_4.dll文件缺失或损坏?故障原因全方位解析与终极修复方案
电脑·dll·dll修复·dll错误
qq_369224331 个月前
打开剪辑/直播/播放器提示ffmpeg.dll丢失?专属场景修复方法汇总
ffmpeg·dll·dll修复·dll错误
qq_369224331 个月前
Windows系统缺失ddraw.dll文件?游戏闪退、图形报错原因详解及处理办法
windows·游戏·dll·dll修复·dll丢失·dll错误
xxx1x1x1 个月前
极客向:DLL/运行库故障的底层逻辑与自动化修复方案
运维·自动化·dll文件·dll·dll修复·dll缺失·dll一键修复
okk1kk1 个月前
一键修复 DLL 缺失报错!彻底解决程序闪退、找不到入口点难题
dll文件·dll·dll修复·dll缺失·dll恢复
qq_369224331 个月前
运行程序闪退、缺少vcruntime140_1.dll?Windows系统通用解决方案
windows·dll·dll修复·dll丢失·dll错误
xxx1x1x2 个月前
一键下载DLL 文件,链接在这里
dll文件·dll·dll修复·dll缺失·dll一键修复·dll还原·dll官方文件