首页 > 代码库 > 动态链接库的加载

动态链接库的加载

 

隐式加载:

  隐式加载又叫载入时加载,指在主程序载入内存时搜索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外释放

动态链接库的加载