DLL 延迟加载与资源释放

DLL延迟加载与资源释放延迟加载DLL的延迟加载技术,使用延迟加载方式编译连接可执行文件。这样可执行文件可以先加载执行,而依赖的dll文件会在正式调用的时候被加载进来。好处是可以把必须使用的D

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

DLL 延迟加载与资源释放

延迟加载

DLL的延迟加载技术,使用延迟加载方式编译连接可执行文件。这样可执行文件可以先加载执行,而依赖的dll文件会在正式调用的时候被加载进来。

好处是可以把必须使用的DLL文件以资源方式插入到程序中并且使用延迟加载。在程序运行时把DLL文件释放到本地,然后进行加载。这样exe并不需要依附DLL文件。并且不会担心DLL丢失。

延迟加载实现

延迟加载并不需要代码来实现,只需要对VS链接属性进行设置即可

属性—>链接器—>输入—>延迟加载的DLL—>输入:dll名称

 DLL 延迟加载与资源释放

DLL延迟加载技术的原理,其实就是在导入表中去掉我们想要隐藏的DLL这一项,等到DLL被正式调用的时候,才会加载DLL文件。这样,程序在正式调用DLL之前,都是可以正常执行的。

资源释放

#include <iostream>
#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)(int a,int b);
	
	// 释放DLL
// 获取当前目录
	char szCurrentPath[MAX_PATH] = { 0 };
	GetCurrentPath(szCurrentPath, MAX_PATH);
	// 构造路径
	::lstrcat(szCurrentPath, "\\hello_world.dll");
	FreeMyResource(IDR_TEST1, "test", szCurrentPath);
	HINSTANCE hDll = LoadLibrary("hello_world.dll");
	_pHello hello = (_pHello)GetProcAddress(hDll, "add");
	int nHello = hello(1,2);
	std::cout << nHello << std::endl;

 DLL 延迟加载与资源释放

查看导入表

 DLL 延迟加载与资源释放

但可以根据PE结构中的资源表IMAGE_RESOURCE_DIRECTORY来解析PE中的所有资源,获取资源的偏移地址和数据大小。

 DLL 延迟加载与资源释放

Tips

  1. 关于如果Visual Studio 2019 出现const char *“ 类型的实参与 “LPCWSTR“ 类型的形参不兼容这类错误。需要修改字符集
  2. 关于如果Visual Studio 2019 出现4996类错误。右击项目文件 — 单击属性 — 配置属性 — c/c++ — 语言 — 符合模式修改符合模式为否。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119851.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 存储过程调试

    存储过程调试

    2021年12月6日
    110
  • matlab自带的插值函数interp1的几种插值方法

    matlab自带的插值函数interp1的几种插值方法插值法    插值法又称“内插法”,是利用函数f(x)在某区间中已知的若干点的函数值,作出适当的特定函数,在区间的其他点上用这特定函数的值作为函数f(x)的近似值,这种方法称为插值法。如果这特定函数是多项式,就称它为插值多项式。线性插值法    线性插值法是指使用连接两个已知量的直线来确定在这两个已知量之间的一个未知量的值的方法。    假设我们已知坐标(x0,y0)与…

    2022年6月13日
    39
  • Linux查看端口使用状态、关闭端口方法

    Linux查看端口使用状态、关闭端口方法前提:首先你必须知道,端口不是独立存在的,它是依附于进程的。某个进程开启,那么它对应的端口就开启了,进程关闭,则该端口也就关闭了。下次若某个进程再次开启,则相应的端口也再次开启。而不要纯粹的理解为关闭掉某个端口,不过可以禁用某个端口。1.可以通过”netstat-anp”来查看哪些端口被打开。(注:加参数’-n’会将应用程序转为端口显示,即数字格式的地址,如:nfs->2049,

    2022年7月20日
    24
  • 手把手教你在Linux环境下安装Python3「建议收藏」

    在上一篇文章《手把手教你启用Win10的Linux子系统(超详细)》我们已经学了如何在Win10环境下装Linux子系统了,那么这一篇文章我们将学习如何在该Linux系统下安装Python3。首先是按Win+R键调出cmd命令窗口,然后输入输入bash指令进入Ubuntu系统,接着就可以进入正式的安装过程了。第一步、下载Python3输入下载命令:wgethttps://w…

    2022年4月17日
    39
  • HQChart实战教程41 -新浪+腾讯A股数据源对接 – uniapp版本 (源码付费)「建议收藏」

    HQChart实战教程41-新浪+腾讯A股数据源对接-uniapp版本数据源支持周期平台支持demo安卓apk下载源码售价580元效果截图HQChart代码地址数据源使用公开的新浪+腾讯的A股票Api数据,h5页面需要自己配代理跨域.app直接就可以访问,无需自己提供数据后台.支持周期分时,5日,日K,周K,1分钟K,5分钟K,15分钟K,30分钟K,36分钟K平台支持uniapp开发,支持h5和appdemo安卓apk下载https://opensource

    2022年4月15日
    88
  • adb 环境变量配置 无效

    今天adb日常抽风。怎么搞就是打不开。由于是新做的系统。所以还没配置adb的环境变量。要打adb还要切到指定文件夹下太麻烦,于是就打算设置下adb的系统变量。结果设置了很多次。发现在cmd中打adb还是提示不是内部命令。也就是说提示我系统变量没有添加成功。重启了几遍有好好仔细检查了下分好和路径。都没问题。最后突然灵光一闪。Win+R输入cmd木有直接回车进入命令行。而是右键了上面的cmd…

    2022年4月9日
    38

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号