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库静态加载和动态加载的理解,便于以后项目开发中选择合适的加载方式。
————————————————
版权声明:本文为CSDN博主「luyumiao1990」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/luyumiao1990/article/details/107184447
DLL的两种加载方式的更多相关文章
- dll的两种加载方式(pend)+ delayload
看过关于动态库的调用例子,于是决定动手做一做:dll的对外接口声明头文件,Mydll.h: //Mydll.h #include <stdio.h> #include <stdlib ...
- Linux共享库两种加载方式简述
Linux共享库两种加载方式简述 动态库技术通常能减少程序的大小,节省空间,提高效率,具有很高的灵活性,对于升级软件版本也更加容易.与静态库不同,动态库里面的函数不是执行程序本身 的一部分,而是 ...
- Xamarin Android Fragment的两种加载方式
android Fragment的重点: 3.0版本后引入,即minSdk要大于11 Fragment需要嵌套在Activity中使用,当然也可以嵌套到另外一个Fragment中,但这个被嵌套的Fra ...
- ios 图片的两种加载方式
控件加载图片,plist,懒加载,序列帧动画,添加动画效果. IOS中有2种加载图片的方式. 方式一:有缓存(图片所占用的内存会一直停留在程序中) + (UIImage *)imageNamed:(N ...
- 渐进式jpeg(progressive jpeg)图片及其相关 --图片的两种加载方式
渐进式jpeg(progressive jpeg)图片及其相关 一.基本JPEG(baseline jpeg)和渐进JPEG 网络上那些色色的照片都是.jpg格式的("色色"指 ...
- Linux驱动的两种加载方式过程分析
一.概念简述 在Linux下可以通过两种方式加载驱动程序:静态加载和动态加载. 静态加载就是把驱动程序直接编译进内核,系统启动后可以直接调用.静态加载的缺点是调试起来比较麻烦,每次修改一个地方都要重新 ...
- Qml文件的两种加载方式
一种是QQmlApplicationEngine搭配Window,例如: #include <QGuiApplication> #include <QQmlApplicationEn ...
- 二、从GitHub浏览Prism示例代码的方式入门WPF下的Prism之Modules的几种加载方式
这一篇梳理Prism中07示例Module的几种加载方式. 07示例分为了5个,有5种不同的Module加载方式. 我们开始学习加载Modules 观察07-Modules-Appconfig示例 分 ...
- Android Activity四种加载方式
Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...
随机推荐
- 二十八、Helm
使用Helm3管理复杂应用的部署 认识Helm 为什么有helm? Helm是什么? kubernetes的包管理器,"可以将Helm看作Linux系统下的apt-get/yum" ...
- 优雅的写好Vue项目代码 — 路由拆分、Vuex模块拆分、element按需加载
目录 路由的拆分 VUEX模块拆分 Element UI库按需加载的优雅写法 路由的拆分 项目较大路由较多时,路由拆分是一个不错的代码优化方案,按不同业务分为多个模块,结构清晰便于统一管理. requ ...
- react的组件通信
react的组件通信 1.父组件传子组件 import React, {Component} from 'react'class Father extends Component{ render() ...
- javax.script.ScriptException: Cannot find engine named: 'nashorn', ensure you set language field in JSR223 Test Element: JSR223 预处理程序
jmeter运行脚本报错,跟java版本有关,做个记录. 1. 问题记录: 执行登录接口测试,登录失败.点击jmeter右上角[黄色!],查看错误日志.显示如下: 2022-09-23 10:29:5 ...
- LoadRunner11脚本小技能之同步/异步接口分离+批量替换请求头
最近在公司又进行了一次LoadRunner11性能测试,技能又get了一点,继续Mark起来!!! 一.异步/同步接口分离 之前在另一篇博文中有提到"事务拆分"的小节,即一个htm ...
- 解决头部使用 position:fixed; 固定定位后遮住下方内容的问题
1.在头部下面给一个空的 div 给这个div设置高度,把页面撑开,这种方法是让头部刚好遮住的是这个空div,把内容放出来. 但是这种方法需要一点点调试高度,所以不推荐. 2.把整个要使用 posit ...
- MASA Framework -- 跨进程事件 IntegrationEventBus入门与设计
概述 跨进程事件总线允许发布和订阅跨服务传输的消息, 服务的发布与订阅不在同一个进程中 在Masa Framework中, 跨进程总线事件提供了一个可以被开箱即用的程序 IntegrationEven ...
- CPU体系(2):ARM Store Buffer
本文主要翻译自 Arm Cortex-M7 Processor Technical Reference Manual r1p2 其中章节 Memory System / L1 caches / Sto ...
- 小米mini路由器刷breed不死鸟和潘多拉固件
前言 开启小米路由器ssh, 这一步浪费我很长时间,因为目前的开发版都对ssh升级进行了md5校验,导致官方升级方法总是失败,所以换成老版本的 路由器固件就行了. 步骤 下载 0.4.36 mini路 ...
- ArcEngine 释放对象
释放对象 例如IFeatureCursor,IFeatureClass等 ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(myFeatureCursor); ...