什么是动态加载?
之前我们都是用的是自动加载,他是在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