案例简述

在某项目中,需要使用两个不同版本的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的两种加载方式的更多相关文章

  1. dll的两种加载方式(pend)+ delayload

    看过关于动态库的调用例子,于是决定动手做一做:dll的对外接口声明头文件,Mydll.h: //Mydll.h #include <stdio.h> #include <stdlib ...

  2. Linux共享库两种加载方式简述

      Linux共享库两种加载方式简述  动态库技术通常能减少程序的大小,节省空间,提高效率,具有很高的灵活性,对于升级软件版本也更加容易.与静态库不同,动态库里面的函数不是执行程序本身 的一部分,而是 ...

  3. Xamarin Android Fragment的两种加载方式

    android Fragment的重点: 3.0版本后引入,即minSdk要大于11 Fragment需要嵌套在Activity中使用,当然也可以嵌套到另外一个Fragment中,但这个被嵌套的Fra ...

  4. ios 图片的两种加载方式

    控件加载图片,plist,懒加载,序列帧动画,添加动画效果. IOS中有2种加载图片的方式. 方式一:有缓存(图片所占用的内存会一直停留在程序中) + (UIImage *)imageNamed:(N ...

  5. 渐进式jpeg(progressive jpeg)图片及其相关 --图片的两种加载方式

    渐进式jpeg(progressive jpeg)图片及其相关   一.基本JPEG(baseline jpeg)和渐进JPEG 网络上那些色色的照片都是.jpg格式的("色色"指 ...

  6. Linux驱动的两种加载方式过程分析

    一.概念简述 在Linux下可以通过两种方式加载驱动程序:静态加载和动态加载. 静态加载就是把驱动程序直接编译进内核,系统启动后可以直接调用.静态加载的缺点是调试起来比较麻烦,每次修改一个地方都要重新 ...

  7. Qml文件的两种加载方式

    一种是QQmlApplicationEngine搭配Window,例如: #include <QGuiApplication> #include <QQmlApplicationEn ...

  8. 二、从GitHub浏览Prism示例代码的方式入门WPF下的Prism之Modules的几种加载方式

    这一篇梳理Prism中07示例Module的几种加载方式. 07示例分为了5个,有5种不同的Module加载方式. 我们开始学习加载Modules 观察07-Modules-Appconfig示例 分 ...

  9. Android Activity四种加载方式

    Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...

随机推荐

  1. Python基础部分:2、 对计算机的认识和python解释器

    目录 一.计算机五大组成部分 1.控制器 2.运算器 3.储存器 4.输入设备 5.输出设备 二.计算机三大核心硬件 1.cpu 2.内存 3.硬盘 三.操作系统 四.编程与编程语言 1.编程语言 2 ...

  2. C# 获取打开的EXCEL中某列的行数

    背景 在通过C#操作EXCEL时 获取行数 int iRowCount = worksheet.get_Range("A65535", oMissing).get_End(MExc ...

  3. Docker | 常用命令——排错很有帮助

    众所周知,docker 排查问题相较而言是困难的.因此,熟知一些常用命令对我们快速的排查定位问题是非常有帮助的.下面让我们一起来学习一下吧 1.显示docker的系统信息 docker info [r ...

  4. Idea在windows和mac中的一些快捷指令

    从 Windows 过度到 Mac 必备快捷键对照表 Mac 键盘符号说明 ⌘ == Command ⇧ == Shift ⇪ == Caps Lock ⌥ == Option ⌃ == Contro ...

  5. GO语言内存操作指导—unsafe的使用

    在unsafe包里面,官方的说明是:A uintptr is an integer, not a reference.Converting a Pointer to a uintptr creates ...

  6. 13.django-admin组件

    Django内置了一个强大的组件叫Admin,提供给网站管理员快速开发运营后台的管理站点,下面通过案例进行操作 1.创建模型类 模型类如下: from django.db import models ...

  7. AIR32F103(六) ADC,I2S,DMA和ADPCM实现录音播放功能

    目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告 AIR32F103(二) Linux环境和LibOpenCM3项目模板 AIR32F103(三) Linux环境基于标准外 ...

  8. java 常用的jar包下载地址

    Eclipse: http://www.eclipse.org/downloads/packages/all Spring: http://Framework: http://repo.spring. ...

  9. 【Shell案例】【awk每行执行一次】11、转置文件的内容

    描述写一个 bash脚本来转置文本文件nowcoder.txt中的文件内容. 为了简单起见,你可以假设:你可以假设每行列数相同,并且每个字段由空格分隔 示例:假设 nowcoder.txt 内容如下: ...

  10. Semaphore信号量源码解析(基于jdk11)

    目录 1.Semaphore信号量源码解析(基于jdk11) 1.1 Semaphore概述 1.2 Semaphore的原理 1.2.1 基本结构(jdk11) 1.2.2 可中断获取信号量 1.2 ...