动态链接库的加载

隐式加载:

  隐式加载又叫载入时加载,指在主程序载入内存时搜索DLL,并将DLL载入内存。隐式加载也会有静态链接库的问题,如果程序稍大,加载时间就会过长,用户不能接受。

显式加载:

  显式加载又叫运行时加载,指主程序在运行过程中需要DLL中的函数时再加载。显式加载是将较大的程序分开加载的,程序运行时只需要将主程序载入内存,软件打开速度快,用户体验好。

  显式加载动态链接库时,需要用到 LoadLibrary() 函数,该函数的作用是将指定的可执行模块映射到调用进程的地址空间。LoadLibrary() 函数的原型声明如下所示:

    HMODULE  LoadLibrary(LPCTSTR 1pFileName);

  显式调用动态库步骤:
    1、创建一个函数指针,其指针数据类型要与调用的 DLL 引出函数相吻合。
    2、通过 Win32 API 函数LoadLibrary()显式的调用DLL,此函数返回DLL 的实例句柄。
    3、通过 Win32 API 函数GetProcAddress()获取要调用的DLL 的函数地址,把结果赋给自定义函数的指针类型。
    4、使用函数指针来调用 DLL 函数。
    5、最后调用完成后,通过 Win32 API 函数FreeLibrary()释放DLL 函数。
  
LoadLibrary() 函数不仅能够加载DLL(.dll),还可以加载可执行模块(.exe)。一般来说,当加载可执行模块时,主要是为了访问该模块内的一些资源,例如位图资源或图标资源等。

  LoadLibrary() 函数有一个字符串类型(LPCTSTR)的参数,该参数指定了可执行模块的名称,既可以是一个.dll文件,也可以是一个.exe文件。

  如果调用成功, LoadLibrary() 函数将返回所加载的那个模块的句柄。该函数的返回类型是HMODULE。 HMODULE类型和HINSTANCE类型可以通用。
  当获取到动态链接库模块的句柄后,接下来就要想办法获取该动态链接库中导出函数的地址,这可以通过调用 GetProcAddress() 函数来实现。

  该函数用来获取DLL导出函数的 地址,其原型声明如下所示: FARPROC  GetProcAddress(HMODULE hModule, LPCSTR 1pProcName);
  可以看到,GetProcAddress函数有两个参数,其含义分别如下所述:

    • hModule:指定动态链接库模块的句柄,即 LoadLibrary() 函数的返回值。
    • 1pProcName:字符串指针,表示DLL中函数的名字。

DLL中内存的分配与释放:

  单个地址空间是由一个可执行模块和若干个D L L模块组成的。这些模块中,有些可以链接到静态版本的C / C + +运行期库,有些可以链接到一个D L L版本的C / C + +运行期库,而有些模块(如果不是用C / C + +编写的话)则根本不需要C / C + +运行期库。许多开发人员经常会犯一个常见的错误,因为他们忘记了若干个C / C + +运行期库可以存在于单个地址空间中。

所以DLL分配的内存最好不要再DLL外释放

时间: 2024-10-10 05:30:48

动态链接库的加载的相关文章

Windows Phone 8加载外部动态链接库DLL(非安装包内的)

Windows Phone 8加载外部动态链接库DLL(非安装包内的) 在<动态加载与插件化>中大概介绍了下,wp8加载非安装包的下动态链接库,这次详细梳理下. 加载外部DLL主要的原理: 通过NtCurrentTeb获得线程环境块 从线程环境块中获得进程环境块 在进程环境块中加载过得DLL链表 从链表中找到kernelbase.dll的模块句柄 从kernelbase.dll中获得LoadLibraryEx函数地址 加载指定地址下的DLL 相关的结构体: typedef struct _CL

React-Native系列Android——SoLoader加载动态链接库

SoLoader是facebook出品的一款小巧的用于加载so库文件的开源项目,主要作用是自动检查和加载多个有依赖关系的so库文件.在Android平台下React-Native项目大量使用了动态链接库,即JNI技术,作为Java和Javascript两种程序语言之间的通信桥梁. 解压一个React-Native项目的安装包apk文件,我们可以看到一共有15个so库文件,其中libreactnativejni.so是JNI桥梁的入口. 而libreactnativejni.so又依赖于以下12个

无法加载 DLL“rasapi32.dll”: 动态链接库(DLL)初始化例程失败。的处理备注方案

网站提示   无法加载 DLL"rasapi32.dll": 动态链接库(DLL)初始化例程失败. (异常来自 HRESULT:0x8007045A). <system.net><defaultProxy><proxy usesystemdefault="false" /></defaultProxy></system.net> 初步怀疑是因为做了云加速服务造成的代理问题,自己瞎猜!反正应该管用

采用dlopen、dlsym、dlclose加载动态链接库【总结】

摘自http://www.cnblogs.com/Anker/p/3746802.html 采用dlopen.dlsym.dlclose加载动态链接库[总结] 1.前言 为了使程序方便扩展,具备通用性,可以采用插件形式.采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件.linux提供了加载和处理动态链接库的系统调用,非常方便.本文先从使用上进行总结,涉及到基本的操作方法,关于动态链接库的本质及如何加载进来,需要进一步学习,后续继续补充.如何将程序设

针对动态加载方式的C/C++动态链接库编写

0.前言笔者为客户提供C/C++动态链接库调用WEBSOCKET功能时,最初错误地认定客户采用静态加载的方式使用DLL库,导致使用其它编程语言的客户无法使用.考虑到为客户服务常常要跨语言和跨IDE,最好的DLL库的使用方式是动态调用,并且要减少DLL库的依赖库,避免对Windows下VS自带库的调用.本文针对动态调用提出一起DLL编写注意事项. 1.静态调用与动态调用1.1 静态调用使用这种方式调用DLL库的步骤(摘自网上url)为,youApp是你DLL的工程名,需要dll\lib\h头文件:

(备忘)vs2010编写动态链接库时导出函数的函数名问题及加载方式

在vs2010中使用.def文件导出函数时,仅仅添加.def文件是不够的,还要在 项目属性 -> 链接器 -> 输入 -> 模块定义文件 中添加自定义的.def文件名. (前提:导入导出都在头文件和源文件中定义好了) ##:静态加载动态链接库 将链接库的 头文件..lib文件 和 .dll 文件拷贝到工程目录下 然后#include 头文件,#pragma comment(lib,"**.lib") 最后直接在需要使用dll函数的地方使用函数就行 ##:动态加载动态链

动态链接库知识点总结之三(如何以显示的方式加载DLL)

总结一下如何显示加载方式加载DLL, 首先,我们新建一个win32项目,选择dll,空项目,再添加一个源文件,一个模块定义文件(.def),具体如下图.(详细方法已经在前两篇文章中讲述,如有不懂,打开链接查看) (1)    新建项目,名称为:dll,添加一个源文件(.cpp),编代码,编译文件 . (2)    为项目添加一个模块定义文件(上一篇文章中详细介绍)(先新建一个文本,再改属性名),编辑代码,如下图 (3)    新建一个DLL测试应用程序(基于对话框的),项目名字:TestDLL,

动态链接库DLL的加载:隐式加载(载入时加载)和显式加载(运行时加载)

静态链接库在链接时,编译器会将 .obj 文件和 .LIB 文件组织成一个 .exe 文件,程序运行时,将全部数据加载到内存. 如果程序体积较大,功能较为复杂,那么加载到内存中的时间就会比较长,最直接的一个例子就是双击打开一个软件,要很久才能看到界面.这是静态链接库的一个弊端. 动态链接库有两种加载方式:隐式加载和显示加载. 隐式加载又叫载入时加载,指在主程序载入内存时搜索DLL,并将DLL载入内存.隐式加载也会有静态链接库的问题,如果程序稍大,加载时间就会过长,用户不能接受. 显式加载又叫运行

【转】采用dlopen、dlsym、dlclose加载动态链接库【总结】

1.前言 为了使程序方便扩展,具备通用性,可以采用插件形式.采用异步事件驱动模型,保证主程序逻辑不变,将各个业务已动态链接库的形式加载进来,这就是所谓的插件.linux提供了加载和处理动态链接库的系统调用,非常方便.本文先从使用上进行总结,涉及到基本的操作方法,关于动态链接库的本质及如何加载进来,需要进一步学习,后续继续补充.如何将程序设计为插件形式,挖掘出主题和业务之间的关系,需要进一步去学习. 2.生产动态链接库 编译参数 gcc -fPIC -shared  例如将如下程序编译为动态链接库