使用场景:
(1)我们会有这种需求,比如版本升级,新版本的dll导出一些函数是旧的dll没有的,但是同时要导出旧的dll原先存在的一些函数,而这些函数功能都没有发生变化,一般而言对于这些原本已经存在的函数,我们可能会直接将源码拷贝到新dll工程,一起整合导出,或者新dll也导出那个函数,只不过它自己什么都不做,只是简单的调用旧的dll函数,有没有更便捷的方式?
(1)我们会有这种需求,比如版本升级,新版本的dll导出一些函数是旧的dll没有的,但是同时要导出旧的dll原先存在的一些函数,而这些函数功能都没有发生变化,一般而言对于这些原本已经存在的函数,我们可能会直接将源码拷贝到新dll工程,一起整合导出,或者新dll也导出那个函数,只不过它自己什么都不做,只是简单的调用旧的dll函数,有没有更便捷的方式?
(2)我们想过滤一个系统dll函数(例如用户态的显卡驱动),我们通过自己编写一个dll A,也导出我们需要过滤掉的函数,通过文件过滤的方式让系统在调用系统dll的时候先加载我们的dll A,然后我们再调用系统的dll,但是有些厂商自己会在该dll导出一些他自己内部调用的函数,这些函数的参数我们也不得而知,为不影响整个系统的调用我们也要跟着导出这些函数,如何导出呢?
《Windows核心编程》有一章简单的介绍了dll forward技术,能有效的解决这两种场景。
为简单的验证这功能,我编写了简单的例子来测试:先编dllA,导出两个函数:Add和Minus:
extern "C" __declspec(dllexport)
int Add(int a, int b)
{
return a + b;
}
extern "C" __declspec(dllexport)
int Minus(int a, int b)
{
return a - b;
}
再编写dllB,导出函数Add、Minus、Multiply,其中Add函数和Minus函数直接使用dllA的导出函数:
#pragma comment(linker, "/export:Add=DllA.Add")
#pragma comment(linker, "/export:Minus=DllA.Minus")
extern "C" __declspec(dllexport)
int Multiply(int a, int b)
{
return a * b;
}
然后编写测试程序调用:
#include "stdafx.h"
#include <windows.h>
typedef int (*fnMultiply)(int a, int b);
typedef int(*fnAdd)(int a, int b);
typedef int(*fnMinus)(int a, int b);
int main()
{
HINSTANCE hDll = LoadLibrary(_T("DllB.dll"));
if (hDll == nullptr) {
return -1;
}
fnMultiply pMultiply = (fnMultiply)GetProcAddress(hDll, "Multiply");
fnAdd pAdd = (fnAdd)GetProcAddress(hDll, "Add");
fnMinus pMinus = (fnMinus)GetProcAddress(hDll, "Minus");
if (pMultiply == nullptr) {
printf("pMultiply == nullptr\n");
FreeLibrary(hDll);
return -1;
}
if (pAdd == nullptr) {
printf("pAdd == nullptr\n");
FreeLibrary(hDll);
return -1;
}
if (pMinus == nullptr) {
printf("pMinus == nullptr\n");
FreeLibrary(hDll);
return -1;
}
printf("1+2=%d\n", pAdd(1, 2));
printf("2-1=%d\n", pMinus(2, 1));
printf("2*1=%d\n", pMultiply(2, 1));
getchar();
FreeLibrary(hDll);
return 0;
}
结果: