DLL的两种加载方式——静态加载和动态加载
案例简述在某项目中,需要使用两个不同版本的HCNetSDK库,我们通常使用的静态加载DLL的方式不能满足该需求,故用到动态加载DLL的方式。背景技术及术语解释静态加载:也称隐式调用,指在运行程序之前由操作系统的加载器将DLL和EXE一起加载到内存里。注意这里与程序的静态链接区别开来,静态链接发生在编译过程之中,而DLL的静态加载是发生在程序运行之前。动态加载:也称显示调用,指应用程序运行过程中程序
- 案例简述
在某项目中,需要使用两个不同版本的HCNetSDK库,我们通常使用的静态加载DLL的方式不能满足该需求,故用到动态加载DLL的方式。
- 背景技术及术语解释
静态加载:也称隐式调用,指在运行程序之前由操作系统的加载器将DLL和EXE一起加载到内存里。注意这里与程序的静态链接区别开来,静态链接发生在编译过程之中,而DLL的静态加载是发生在程序运行之前。
动态加载:也称显示调用,指应用程序运行过程中程序自己完成对DLL的加载和卸载(DLL加载—DLL函数地址获取—DLL释放),应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件。
- 详细描述
- 静态加载DLL
静态加载DLL需要提供.h、.lib、.dll文件,假设需要加载的DLL文件名为MyDll.dll,静态加载DLL步骤如下:
(1)将MyDll.dll拷到目标工程(需调用MyDll.dll的工程)的Debug目录下;
(2)将MyDll.lib拷到目标工程(需调用MyDll.dll的工程)目录下;
(3)将MyDll.h(包含输出函数的定义)拷到目标工程(需调用MyDll.dll的工程)目录下;
(4)打开目标工程,选中目标工程名点击右键,依次选择【属性】-【配置属性】-【链接器】-【输入】,在附加依赖项中输入:MyDll.lib;
(5)在目标工程Head Files加入MyDll.h文件;
(6)在目标工程(*.cpp,需要调用MyDll.dll中的接口)中包含头文件,即#include “MyDll.h”,然后在该*.cpp中可直接调用MyDll.h中的接口。
- 动态加载DLL
动态加载DLL不需要依赖.h和.lib文件,仅需要将.dll文件拷贝到应用程序所在目录下。
动态加载需主要用到LoadLibrary(加载DLL)、GetProcAddress(获得DLL中API函数的地址)、FreeLibrary(释放DLL)这几个系统函数。
LoadLibrary() 函数作用是将指定的可执行模块映射到调用进程的地址空间,如果调用成功, LoadLibrary() 函数将返回所加载的那个模块的句柄。当获取到动态链接库模块的句柄后,接下来就要想办法获取DLL导出函数的地址,这可以通过调用 GetProcAddress() 函数来实现。当DLL文件中的函数不再使用或程序结束时,需要使用FreeLibrary()函数对其进行释放。具体使用示例如下:
加载DLL:
#include <windows.h>
HINSTANCE hDllInst = LoadLibrary(“MyDll.dll”);
调用DLL中函数:
typedef BOOL (CALLBACK * pwmNET_DVR_Logout_V30)(long lUserID);
BOOL CLASSNAME::NET_DVR_Logout_V30(long lUserID)
{
pwmNET_DVR_Logout_V30 pNET_DVR_Logout_V30 = (pwmNET_DVR_Logout_V30)GetProcAddress(hDllInst, " NET_DVR_Logout_V30");
if (NULL == pNET_DVR_Logout_V30)
{
PAG_ERROR(">>> GetProcAddress [NET_DVR_Logout_V30] Failed!");
return FALSE;
}
return pNET_DVR_Logout_V30(lUserID);
}
释放DLL:
if(hDllInst!= NULL)
{
FreeLibrary(hDllInst);
}
- 静态加载与动态加载区别
(1)加载时间:静态加载发生在程序运行之前,故如果缺少dll文件,程序运行不起来。动态加载发生在程序运行过程中(由编程者决定何时加载),不会因为缺少dll,导致整个程序运行不起来。如果程序体积较大,功能较为复杂,静态加载会导致程序启动时间长。而动态加载可将较大的程序分开加载的,程序运行时只需要将主程序载入内存,程序启动快。
(2)依赖文件:静态加载需要.lib和.dll文件,动态加载只需要.dll文件。
(3)占用内存: 静态加载占用内存较大。静态加载可以在需要的时候用LoadLibrary进行加载,在不需要的时候用FreeLibrary进行卸载,这样可以不必占用内存。
(4)使用情况:静态加载使用简单方便。动态加载使用复杂一些,需要显示获取函数地址。
- 贡献点
(1)介绍了DLL库静态加载和动态加载的方法及其区别。
(2) 加深了对DLL库静态加载和动态加载的理解,便于以后项目开发中选择合适的加载方式。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)