动态链接库加载的两种方式

目录

1. 隐式链接

xxx.lib -- 引入库文件,保存的是xxx.dll中导出的函数和变量的符号名

xxx.dll -- 导出的动态链接库

四大路径及顺序

extern与__declspec(dllimport)区别

推荐工具 Dependency Walker 2.2:查看一个可执行程序所依赖的动态链接库,

2. 显式加载(动态加载)

相关函数

参考阅读

示例代码

3.隐式链接与显式加载对比


 


1. 隐式链接

 

xxx.lib -- 引入库文件,保存的是xxx.dll中导出的函数和变量的符号名

不会包含实际代码,为链接程序提供必要的信息,以便在可执行文件中建立 动态链接时需要用到的 重定位表

只是提供一种映射关系

VS2013中是在这个位置添加:

动态链接库加载的两种方式_第1张图片

xxx.dll -- 导出的动态链接库

需要放置在这些位置下才可以被程序找到

四大路径及顺序

1. 程序的执行路径

2. 当前路径(.)【一个点代表当前路径,两个点代表上层路径】

3. 系统路径

例如C:\Windows\System,C:\Windows\System32,C:\Windows\SysWOW64

4. 系统环境变量(PATH)中所列出的路径

举例说明:调用OpenCV的dll时一般放置在程序的执行路径(1),或者把它添加到系统环境变量(PATH)中(4)。

参考博客

VS2013与OpenCV3配置

 

extern与__declspec(dllimport)区别

__declspec(dllimport)会告诉编译器该函数是从动态链接库引入的,编译器可以生成运行效率更高的代码。

如果调用的函数来自于动态链接库,应该采用这种方式声明外部函数。

 

推荐工具 Dependency Walker 2.2:查看一个可执行程序所依赖的动态链接库,

下载地址与更多信息可参考 http://www.dependencywalker.com/

 

 

2. 显式加载(动态加载)

相关函数

HMODULE WINAPI LoadLibrary(
  _In_ LPCTSTR lpFileName
);

FARPROC GetProcAddress(
  HMODULE hModule,
  LPCWSTR lpProcName
);


BOOL FreeLibrary(
  HMODULE hLibModule
);

【注意】每调用一次 LoadLibrary 函数就应调用一次 FreeLibrary 函数,以保证不会有多余的库模块在应用程序结束后仍留在内存中,否则导致内存泄漏。

参考阅读

 

LoadLibrary

GetProcAddress

FreeLibrary

 

示例代码

HINSTANCE hInst;
hInst = LoadLibrary("MyDll2.dll");      //显式加载(动态加载)dll
typedef int (*ADDPROC) (int a, int b);  //定义函数指针类型
ADDPROC Add = (ADDPROC)GetProcAddress(hInst, "add");    //获取dll的导出函数
if(!Add){
    MessageBox("获取函数地址失败!");
    return;
}
FreeLibrary(hInst);

也可以参考如下博客

Windows API封装:LoadLibrary/FreeLibrary

Windows LoadLibrary使用示例

LoadLibrary方法加载运行DLL

3.隐式链接与显式加载对比

  隐式链接 显式加载
需要的文件 .lib/.dll/.h .dll
何时被加载至内存中 程序启动时 需要时才加载
同时加载多个dll时的资源浪费情况 严重 一般
使用方便程度 非常 一般
使用dumpbin -imports查看调用者 有信息 无信息
特别说明 本质上,隐式链接是在程序启动时通过LoadLibrary方式加载dll

【注意】不管哪种方式,dll都需要被调用者找到才可以,参考上面的“四大路径及顺序”。

 

更多内容请看C/C++动态链接库(DLL)详解

来源:孙鑫_VC++_学习笔记

你可能感兴趣的:(C/C++,VC++深入详解)