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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm中debug无法调试_pycharm配置debug

    pycharm中debug无法调试_pycharm配置debug在多次跑项目中遇到情况,pacharm突然就无法运行项目了,表现就是run和debug两个选项按钮全部变灰色无法点击。造成这种情况的原因是因为我在一个很大的文件下创建了新的文件,每次运行都要为所有文件建造索引,文件很大的话这个时间就比较长,表现就是右下角有个进度条一直在刷新。这个时候的做法就是:右键文件名——&gt; Markdirectoryas… ——&gt;Exclude…

    2022年8月29日
    8
  • Kafka动态调整topic分区partition

    Kafka动态调整topic分区partition我们在使用kafka时,初期创建时所指定topic属性需要修改,如何动态修改kafka属性?kafka提供了命令行工具—kafka-topics.sh.kafka-topics.sh工具介绍kafka-topics.sh工具也是我们用来创建topic、查看topic详情的工具。直接运行kafka-topics.sh可以产出它是用来创建、删除、查看以及更新topicroot@ubuntu……

    2022年10月17日
    2
  • 外行假装内行,我也来谈谈SAP BAPI和BADI

    外行假装内行,我也来谈谈SAP BAPI和BADI外行假装内行,我也来谈谈SAPBAPI和BADIA,什么是BAPI?BAPI是businessapplicationprogramminginterface的缩写,是面向对象程序设计方法中的一组程序接口。它允许程序员通过SAP将第三方软件整合成R/3专有产品。为了完成一些特殊的商业任务,如上传交易数据等,R/3系统中内置了BAPI。1.BAPI–businessapplicationprogramminginterface。2.它实际上是一种特殊的

    2022年7月24日
    10
  • Ubuntu16.04安装搜狗拼音输入法(中文输入法)「建议收藏」

    Ubuntu16.04安装搜狗拼音输入法(中文输入法)「建议收藏」虽然网上有很多教程,但是我觉得我的很适合那些真正的小白。。。1、下载文件由于我要给多台电脑安装搜狗输入法,所以用的是文件夹安装,不是命令行安装。打开官网http://pinyin.sogou.c

    2022年8月2日
    4
  • python 数字转换字符串(python转换字符串)

    原博文2019-06-3001:20−字符串->数字:int(字符串),float(字符串)数字->字符串:str(数字)…01602相关推荐2019-12-1214:34−##Python代码块、缓存机制1.相同的字符串在Python中地址相同“`pythons1=’panda’s2=’panda’print(s1==s2…

    2022年4月16日
    77
  • Tomcat全攻略

    Tomcat全攻略

    2021年12月15日
    55

发表回复

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

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