dll延迟加载技术
之前说给团队的兄弟们说下dll延迟加载的东西,现在出来了
随便生成一个dll,dll代码如下:
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <iostream>
#include <cstring>
using namespace std;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) int hello()
{
int a = 666;
return a;
}
添加资源后,cpp代码如下:
#include <iostream>
#include<windows.h>
#include "resource.h"
BOOL FreeMyResource(UINT uiResouceName, char* lpszResourceType, char* lpszSaveFileName);
void GetCurrentPath(char* lpszCurrentPath, DWORD dwSize);
void FreeRes_ShowError(char* pszText);
// CDelayLoadDll_TestDlg 消息处理程序
void FreeRes_ShowError(char* pszText)
{
char szErr[MAX_PATH] = { 0 };
::wsprintf(szErr, "%s Error[%d]\n", pszText, ::GetLastError());
::MessageBox(NULL, szErr, "ERROR", MB_OK);
}
// 释放资源
BOOL FreeMyResource(UINT uiResouceName, char* lpszResourceType, char* lpszSaveFileName)
{
HRSRC hRsrc = ::FindResource(NULL, MAKEINTRESOURCE(uiResouceName), lpszResourceType);
if (NULL == hRsrc)
{
FreeRes_ShowError("FindResource");
return FALSE;
}
DWORD dwSize = ::SizeofResource(NULL, hRsrc);
if (0 >= dwSize)
{
FreeRes_ShowError("SizeofResource");
return FALSE;
}
HGLOBAL hGlobal = ::LoadResource(NULL, hRsrc);
if (NULL == hGlobal)
{
FreeRes_ShowError("LoadResource");
return FALSE;
}
LPVOID lpVoid = ::LockResource(hGlobal);
if (NULL == lpVoid)
{
FreeRes_ShowError("LockResource");
return FALSE;
}
FILE* fp = NULL;
fopen_s(&fp, lpszSaveFileName, "wb+");
if (NULL == fp)
{
FreeRes_ShowError("LockResource");
return FALSE;
}
fwrite(lpVoid, sizeof(char), dwSize, fp);
fclose(fp);
return TRUE;
}
// 获取当前目录
void GetCurrentPath(char* lpszCurrentPath, DWORD dwSize)
{
::GetModuleFileName(NULL, lpszCurrentPath, dwSize);
char* p = ::strrchr(lpszCurrentPath, '\\');
p[0] = '\0';
}
int main()
{
typedef int (*_pHello)();
//std::cout << "Hello World!\n";
// 释放DLL
// 获取当前目录
char szCurrentPath[MAX_PATH] = { 0 };
GetCurrentPath(szCurrentPath, MAX_PATH);
// 构造路径
::lstrcat(szCurrentPath, "\\dlltest.dll");
FreeMyResource(IDR_DLLS1, "dlls", szCurrentPath);
HINSTANCE hDll = LoadLibrary("dlltest.dll");
_pHello hello = (_pHello)GetProcAddress(hDll, "hello");
int nHello = hello();
std::cout << nHello << std::endl;
}
FindResource函数原型:
不得不说,这个函数原型的命名有点东西,上网查也说的和命名的情况差不多,,但是实际上传入的参数如图:
真狗啊。。。
在vs上有需要配置的地方否则会报错,都如图所示:
第三个配置顾名思义,前面两个不改的话,会报什么错可以自己尝试下,后面运行结果:
查看程序导入表,并没有这个用到的dll: