VS2017 DLL动态库使用教程【六】动态加载DLL

什么是动态加载?

之前我们都是用的是自动加载,他是在exe运行启动时,就加载dll。

动态加载,在编译的时候不指定dll,根据代码需要时调用LoadLibrary来加载dll。

而且动态加载可以根据程序需时卸载dll,自动加载只能程序结束卸载dll。

动态加载也叫手工加载。

 

如何使用动态加载?

首先我们对之前的dll文件做一个小改动,因为动态加载无需声明头文件(*.h),所以所以有一个很严重的问题——我们不能使用c++的重载特性了,如果你写一个重载函数,比如:

int add(int x,int y);    //把x和y相加
int add(int x,int y,int z);    //把x,y和z相加

但是在dll内,因为他一些规范封装原则,c++函数,在内存中是这样的

_add_int_int  //以函数名+形参的形式储存
_add_int_int_int //x,y,z相加有三个形参,所以三个int

用自动加载,我们有头文件(*.h)帮助引导重载,可是动态加载无需声明头文件,就需要我们把函数声明成c风格的形式。

很简单,只需要在dll的头文件声明一下就可以了。

//如果你看不懂为什么要条件编译,请阅读第四章
#ifndef MYDLL_EXPORTS
#define MYDLL _declspec(dllexport)
#else
#define MYDLL _declspec(dllimport)
#endif // !MYDLL

extern "C" MYDLL int add(int a, int b);    //函数前加extern "C"可以声明c风格,想具有了解可以在网上搜一下。

好了,写好后可以编译,生成dll,然后把他取出来。

然后放到DLLAPP,也就是使用dll的程序目录下。

 

DLLAPP下的唯一main.cpp文件,就和你平时做c++练习一样

代码很多,不要慌,仔细看注释。

#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
int main()
{
	HINSTANCE handle = LoadLibrary("my.dll");//LoadLibrary填入ddl文件名赋值给句柄,你不懂句柄就拉倒了,这个不重要。
	if (handle) //判读句柄内dll是否可用
	{
		typedef int(*DLL_FUNCTION_ADD) (int, int); //typedef定义一下函数指针,你不懂的话就记住末尾两个是你需要函数的形参。
		DLL_FUNCTION_ADD dll_add = (DLL_FUNCTION_ADD)GetProcAddress(handle, "add"); //使用GetProcAddress得到函数,参数是句柄名和函数名
		if (dll_add) //还是判断一下函数指针是否有效
		{
			int result = dll_add(10, 11); //终于可以用add了
			printf("dll_add返回值:%d\n", result); //打印吧
		}
		FreeLibrary(handle); //卸载句柄,,
	}
	
	system("pause");
	return 0;
}

动态加载基本就是这个套路,你需要动态加载可以直接粘贴代码即可。

 

笔记中代码均保存到我的网盘下,链接:https://share.weiyun.com/5HMq3Cc

 

程序中加载了一个DLL文件,但生成的EXE在脱离了DLL文件后仍然可以 单独使用,这是动态加载DLL技术。即:调用资源中的DLL。 此技术的好处:EXE可以使用DLL中的函数,但不会额外增加一 个DLL文件,在使用DLL文件的时候不需要先把DLL释放到硬盘。 在动态加载的这个DLL中定义了一个函数MRun,该函数可以动态执行一 个EXE,即:调用资源中的EXE文件或TMemoryStream中被载入的EXE流。 此技术的好处:直接把资源中的EXE加载到内存中执行,使用程序自 身嵌入的EXE文件的时候不需要先把EXE释放到硬盘上就可以直接执行。 对保密EXE文件很有用。例如:我编写的程序是A.exe,它在运行后需要 使用B.exe,而B.exe是别人编写的我没有源码,但我必须又要在我的程 序中用B.exe,这时我就把它包含到我的A.exe中,这个非常容易做到, 但是,程序A.exe在使用程序B.exe的时候按照常理必须先把B.exe释放 到硬盘上才可以用WinExec或ShellExecute等函数调用它,但你在释放 到硬盘上的时候容易被别人直接复制走,而你只想让别人用你的A.exe不 想让别人直接用B.exe(因为B.exe是别人写的等原因),此时如何保密 B.exe呢?这时只要用到上面所说的MRun函数就可以了,程序A.exe在执 行B.exe的时候不需要释放到硬盘上就可以直接执行B.exe啦,是不是很爽? 说一下MRun的调用方式: MRun(流,参数,进程id); 调用成功返回True,失败返回False,三个参数解释如下: 第一个参数:一个载入了EXE的资源流或者内存流等流类型。 第二个参数:传递调用EXE的参数。如果EXE调用不需要参数,可设置为空串。 第三个参数:如果调用成功,则返回被调用的EXE对应的进程ID。 细节性问题,请直接双击Project1.dpr文件进入演示代码,了解更多。演示代 码中动态加载了MemRun.dll文件,动态调用了5555044.exe文件,如果你想更换 动态调用的EXE文件,只需要用其它EXE覆盖5555044.exe文件并双击Clear.bat 文件后,在Delphi中按F9重新编译运行即可。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值