使用DLL的时机和好处分别是什么呢?

2021-05-07 17:43发布

6条回答
studentaaa
2楼 · 2021-05-08 15:14

静态链接库DLL,动态连接库概念以及使用dll的好处:


静态连接库

静态连接库:Window下以*.lib Linux下以*.a 命名的文件统称;

静态连接库就是把(lib)文件中用到的函数代码直接链接进目标程序,程序发布运行的时候不再需要其它的库文件


动态连接库

动态连接库(Dynamic-link Library,缩写为 DLL):Window下以*.dll Linux下以*.so 命名的文件统称;

动态链接就是把调用的函数所在文件模块(DLL)和调用函数在文件中的位置等信息链接进目标程序,程序运行的时候再从DLL中寻找相应函数代码,因此在发布和运行时需要相应DLL文件的支持


分析

分隔符上边是优点下边是缺点


静态链接库 动态链接库

代码装载速度快,执行速度略比动态链接库快 更加节省内存并减少页面交换

只需保证在开发者的计算机中有正确的.LIB文件,在以二进制形式发布程序时不需考虑在用户的计算机上.LIB文件是否存在及版本问题,可避免DLL地狱等问题 DLL文件与EXE文件独立,只要输出接口不变(即名称、参数、返回值类型和调用约定不变),更换DLL文件不会对EXE文件造成任何影响,因而极大地提高了可维护性和可扩展性

不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数

适用于大规模的软件开发,使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开发和测试

使用静态链接生成的可执行文件体积较大,包含相同的公共代码,造成浪费;是将全部指令包含到可执行程序,要么全要要么全不要 应用程序不是自完备的,依赖的DLL模块必须存在。当某个模块更新后,如果新模块与旧的模块不兼容,那么那些需要修改旧模块才能运,会造成"DLL地狱"

无论动态库还是静态库都包含 .lib文件

我接触的大多是使用动态链接库,静态库对程序的更新、部署和发布页会带来麻烦。如果静态库liba.a更新了,所以使用它的应

用程序都需要重新编译、发布给用户(对于客户来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。   

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存

里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和

发布页会带来麻烦。用户只需要更新动态库即可,增量更新。

静态链接库调用

静态链接库的使用比较简单需要库的开发者提供生成库的.h头文件和.lib文件。生成库的.h头文件中的声明格式如下:


extern "C" 函数返回类型 函数名(参数表);

在调用程序的.cpp源代码文件中如下:


#include "../lib.h"

#pragma comment(lib,"..//debug//libTest.lib")      //指定与静态库一起链接

需要的文件: 头文件 .h 、静态库 .lib

头文件.h中有函数的声明,使用静态链接库的项目需要引用该文件才能编译通过

lib包含了实际执行代码、符号表等等

加载lib的方法: 法1.使用编译链接参数或者VS的配置属性来设置 法2.使用pragma编译语句,例如pragma comment(lib,“a.lib”)

lib中的指令将全部被直接包含在最终生成的 EXE 文件中

动态链接库俩种调用方式

动态链接库的调用方式有俩种比较拗口:静态调用(隐式加载) 和 动态调用(显示加载)


先来说比较常用和简单的隐式加载

需要生成的 lib dll .h 文件 三者缺一不可,配置如下:

vs项目->属性->VC++目录->包含目录:添加头文件所在路径

vs项目->属性->VC++目录->库目录:添加lib文件所在路径

DLL复制到exe执行目录

此处我有个疑问有懂得大佬可以帮我解答下:为什么有的还需要在链接器->附加依赖项中添加 lib文件的全称

什么情况下添加?添加的作用? 是和导出方式有关么


和静态库有什么区别:其实这里生成的 lib 文件是很小的。 它只保存了 dll 文件的符号信息,保证 exe 链接的时候能找到要链接的符号,而运行的时候才是真正加载 dll 来调用函数。静态库的话是会把所有实现都会生成 lib 文件,所以静态的 lib 文件是很大的。


 优点:

1.不需要动态加载 dll 文件和释放。在写代码的时候引入了头文件,对于 dll 导出的函数和数据结构看起来比较清晰。


 缺点:

1.因为隐式加载的 dll 是在 main 函数之前,所以如果缺少了 dll 会影响 exe 的启动。


显式加载


这里大概可以分这几步:1.加载dll文件,2。取得文件内相应函数的指针。3.使用函数。4.释放dll句柄


只需要生成的 dll 文件 ,但是loadLibrary之后可以使用getProcAddress来查找一个函数的地址从而调用该函数,必须知道函数的类型,名称,参数 

DLL复制到exe执行目录


typedef   int(__cdecl*   FunctionAdd)(int,int); // 声明相应的函数指针类型。 

HMODULE   hModule; // 指向dll文件的句柄。

FunctionAdd   add; // 指向相应函数的指针实例。

hModule   =   LoadLibrary("dll1.dll"); // LoadLibrary 将dll1.dll文件加载进内存中来。用句柄指向。文件目录可以任意。

If(NULL==hModule   )

{

 //error.

}

add   =(FunctionAdd)GetProcAddress(hModule,"add"); //根据dll的句柄得到相应函数的指针。

if(NULL==add)

{

 //error

}

int r = add(1,1) ;  // 得到指针后就可以用相应的函数啦。

Wsprintf msgbox

 FreeLibrary(hModule); // 释放dll句柄。

 优点:

1.不需要在 exe 链接的时候放入对应的 lib。

2.加载的 dll 在 main函数之后,是由用户主动操作,可操作空间大。

3.就算目标 dll 丢失,也只会导致 LoadLibrary加载失败,根据业务逻辑来判断是否影响主逻辑。

4.支持热更新,更新了 dll,在进程内部调用 FreeLibrary 然后调用LoadLibrary 加载新的 dll,而不用重启进程。

 缺点:

1.调用之前需要清楚的知道导出函数的定义,来定义函数指针指向它。需要手动加载和释放,如果漏掉了释放可能会造成资源泄露。

根据需求来选择加载模式,比如这个 dll 是程序的主模块,没有的话程序就不能启动,使用隐式加载。而比如dll可能就只是一个插件,这样就可以使用显示加载


声明一个导出函数,是说这个函数要从本DLL导出。我要给别人用。一般用于dll中省掉在DEF文件中手工定义导出哪些函数

的一个方法。当然,如果你的DLL里全是C++的类的话,你无法在DEF里指定导出的函数,只能用__declspec(dllexport)导出类


声明一个导入函数,是说这个函数是从别的DLL导入。我要用。一般用于使用某个dll的exe中 不使用 __declspec(dllimport) 

也能正确编译代码,但使用 __declspec(dllimport) 使编译器可以生成更好的代码。编译器之所以能够生成更好的代码,是因

为它可以确定函数是否存在于 DLL 中,这使得编译器可以生成跳过间接寻址级别的代码,而这些代码通常会出现在跨 DLL 

边界的函数调用中。但是,必须使用 __declspec(dllimport) 才能导入 DLL 中使用的变量。

aijingda
3楼 · 2021-05-08 18:17

使用DLL的好处主要有以下几点:

一、使用较少的资源

  当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在 Windows 操作系统上运行的程序。

二、推广模块式体系结构

  DLL 有助于促进模块式程序的开发。这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。模块式程序的一个示例是具有多个可以在运行时动态加载的模块的记账程序。

三、简化部署和安装

  当 DLL 中的函数需要更新或修复时,部署和安装 DLL 不要求重新建立程序与该 DLL 的链接。此外,如果多个程序使用同一个 DLL,那么多个程序都将从该更新或修复中获益。当您使用定期更新或修复的第三方 DLL 时,此问题可能会更频繁地出现。

小橘子
4楼 · 2021-05-10 10:46
DLL是动态连接库。使用动态连接库的一些好处是:
1.多个应用程序共享代码和数据:比如Office软件的各个组成部分有相似的外观和功能,这就是通过共享动态连接库实现的。
2.在钩子程序过滤系统消息时必须使用动态连接库。
3.动态连接库以一种自然的方式将一个大的应用程序划分为几个小的模块,有利于小组内部成员的分工与合作。而且,各个模块可以独立升级。如果小组中的一个成员开发了一组实用例程,他就可以把这些例程放在一个动态连接库中,让小组的其他成员使用。
4.为了实现应用程序的国际化,往往需要使用动态连接库。使用动态连接库可以将针对某一国家、语言的信息存放在其中。对于不同的版本,使用不同的动态连接库。在使用AppWizard生成应用程序时,我们可以指定资源文件使用的语言,这就是通过提供不同的动态连接库实现的。
5.拓展研发工具的功能,由于DLL是和语言无关的,因此能创建一个DLL,被C++、VB或所有支持动态链接库的语言调用。这样如果一种语言存在不足,就能通过访问另一种语言创建的DLL来弥补。
VC++、C++ Builder、Delphi都可以编写DLL文件。Visual Basic 5.0以上版本也可以编写一种特殊的DLL,即ActiveX DLL。

用DLL 的一个潜在缺点是应用程序不是独立的;它取决于是否存在单独的 DLL 模块。但是好处还是挺大的,最大的好处就是节省内存,程序在没有运行到dll里的函数的时候,dll里的函数就没有运行,只有在运行到了dll,才通过dll的接口函数访问dll,这样比直接把函数代码写到主题函数,或静态链接库相比,运行的效率有了很大的提高.作用是通过使用 DLL,程序可以实现模块化,由相对独立的组件组成。另外可以更为容易地将更新应用于各个模块,而不会影响该程序的其他部分。

Transform
6楼 · 2021-05-11 11:02

动态链接库(Dynamic-Link Library),简称DLL,是基于Windows程序设计的一个非常重要的组成部分。使用DLL有许多优点:(1)使用DLL的动态连接不是将库代码拷贝,只在程序中记录函数的入口点和接口,在程序执行时才将库代码装入内存,如果有多个程序使用相同的DLL,也只需将DLL在内存中装载一次,节省了内存开销。(2)DLL是基于Windows的程序模块,它不仅包含可执行代码,还可以包含数据,各种资源,扩大了库文件的使用范围。(3)对于一个大型的、不断更新的应用程序,可以将许多重复的功能写成DLL,用主程序调用,这样既减少了开发的工作量,又提高了访问速度。。(5)DLL独立于编程语言,大多数WINDOWS编程环境都允许主程序调用DLL中的函数。

梅向南
7楼 · 2021-05-14 16:38

其实动态链接库最大的好处就是节省内存,程序在没有运行到dll里的函数的时候,dll里的函数就没有运行,只有在运行到了dll,才通过dll的接口函数访问dll,这样比直接把函数代码写到主题函数,或静态链接库相比,运行的效率有了很大的提高。

相关问题推荐

  • 回答 6

    第一步:对着Assets点击右键,选择ExportPackage第二步:选择场景文件以及和场景相关的资源或者素材,然后点击Export第三步:给导出的资源取名,并且选择要保存的位置即可

  • 回答 87
    已采纳

    玩游戏玩的很好,说明你对于游戏里面的规则、剧情设置还是比较了解的,对于从事游戏相关岗位来说也是优势之一。但是学习游戏开发还是要对游戏开发的工作内容做进一步的了解,游戏开发涉及代码较多,可以通过进一步的了解,判断自己是否适合学习这个方向,另外...

  • 回答 11

    游戏开发入门不难。后期发展需要你有丰富的奇思妙想。游戏开发肯定是培训好,自学学得不系统,并且不易发现自身薄弱之处。游戏开发的学习时长还是要看你自己对知识与技术的掌握能力,一般来说,游戏开发的学习时长大约在五个月左右。...

  • 回答 18

    个人觉得如果有一定的技术基础的话还是可以考虑自学,如果零基础的话可能会有些难度

  • 回答 10

    问题还是出在粒子的sorting fudge。在unity的2d模式下,游戏本身的背景相当于是sorting fudge的0,当你把粒子的sorting fudge设为0以上的时候,粒子就都会被背景盖住。所以在3d模式下给alpha正值来给add垫底的话,到了2d模式下就会通通不显示。所以遇上这样的...

  • 回答 17

    虚幻4引擎,你会看到和平精英加载页面左下角有这个图标。

  • 回答 8
    已采纳

    转载知乎上的两位答友的回答,各有道理。作者:风小锐链接:https://www.zhihu.com/question/322249959/answer/675883379来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。未来Unity有可能出现3A大作吗? 有可能。基于Unity已...

  • 回答 11

    在Assets文件夹里面.点击右键Create/Material即可以创建材质球

  • 回答 23

    可以让模型师直接作出这样的形状,如果用纯Unity制作,就要用基本游戏对象拼接了,包括楼梯,城堡,都可以拼接出来。正常情况不会这样做,因为不够精美,都是建模师来实现,毕竟Unity不属于专业的建模软件,侧重于实现功能。...

  • 回答 18

    粒子系统由粒子发射器、粒子动画器和粒子渲染器三部分组成,主要用于游戏场景中一些特殊效果,如水、烟火等等

  • 回答 18

    首先,Python开发游戏非常尴尬,原因是没有好用的游戏开发库。Python开发游戏仅推荐PyGame,PyGame是对多年以前很流行的游戏开发库——SDL的封装。但是说实话功能太简陋了,做个动画都得考虑刷新的问题。楼主要做简单小游戏,只需要画一两周熟悉Unity引擎,然...

  • 回答 9

    1.标记水体碰撞的位置2.计算水波的传递 通过波动公式,3D或者2D 波动公式都行3.水面顶点采样波动传递结果计算结果做顶点Y轴偏移

  • 回答 15

    Unity3D中两种阴影的实现传统的ShadowMapShadowMap说起来十分简单,把摄像机和光源的位置重叠,那么场景中该光源的阴影区域就是那些摄像机看不到的地方,主要应用在前向渲染路径中。具体实现分以下几个步骤:如果有平行光开启了阴影,Unity就会为该光源计算它...

  • 回答 18

    Doozy UI是Unity UI视图层的框架,本身使用的还是UGUI的组件,但提供了一套强大的UI管理功能,可以很方便的实现一些炫酷效果,方便的UI系统管理与事件传递机制。

  • 回答 12

    Unity3d更好,因为U3D占有的市场更大,目前cocos大都是用来开发棋牌游戏的,在这方面它有着巨大的优势。而Unity3d既可以用来开发大型3D游戏,也可以用来开发vr游戏、vr应用,这是比较不错的,未来有着巨大的前景。另外ue4也是个不错的选择,近年来用ue4开发的...

  • 回答 11

    当Unity 需要做热更新的时候(2013年开始),而普通的C#又做不到的时候,而对于游戏行业来说Lua脚本热更新已经是很成熟的方案,自然Lua 热更新就成为了Unity热更新的首选。

没有解决我的问题,去提问