C++中显示与隐式加载dll的使用与区别

 更新时间:2025年12月19日 10:13:27   作者:wangnaisheng  
本文主要介绍了C++中显示与隐式加载dll的使用与区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、什么是 DLL?

DLL(Dynamic Link Library) 是 Windows 下的动态链接库,包含可被多个程序共享的函数、资源或类。使用 DLL 可以实现代码复用、模块化设计和插件机制。

在 C++ 中,调用 DLL 中的函数有两种主要方式:

  1. 隐式链接(Implicit Linking)
  2. 显式链接(Explicit Linking)

二、隐式链接(Implicit Linking)

1. 原理

程序启动时自动加载 DLL,通过 .lib 导入库将 DLL 中的函数符号链接到可执行文件中。

2. 使用步骤

(1)准备三个文件:

  • MyDll.dll:动态库文件
  • MyDll.lib:导入库(由 DLL 生成)
  • MyDll.h:声明导出函数

(2)头文件示例(MyDll.h)

#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllimport) int Add(int a, int b);

#ifdef __cplusplus
}
#endif

注意:dllimport 表示从 DLL 导入函数。

(3)链接 .lib 文件

在项目中添加 .lib 路径,并链接:

#pragma comment(lib, "MyDll.lib")

(4)直接调用函数

#include "MyDll.h"

int result = Add(3, 4); // 直接像普通函数一样调用

3. 特点

优点缺点
使用简单,像调用本地函数启动时必须找到 DLL,否则程序无法启动
编译期检查函数签名不支持动态选择或延迟加载
性能略高(无需查表)难以实现插件系统或热更新

三、显式链接(Explicit Linking)

1. 原理

运行时通过 LoadLibraryGetProcAddress 手动加载 DLL 并获取函数地址。

2. 使用步骤

(1)不需要 .lib 文件,只需:

  • MyDll.dll
  • MyDll.h(知道函数原型)

(2)加载 DLL 并获取函数指针

#include <windows.h>
#include <iostream>

// 定义函数指针类型
typedef int (*AddFunc)(int, int);

int main()
{
    HMODULE hDll = LoadLibrary(_T("MyDll.dll")); // 加载 DLL

    if (hDll == NULL) {
        std::cout << "无法加载 DLL!" << std::endl;
        return -1;
    }

    // 获取函数地址
    AddFunc Add = (AddFunc)GetProcAddress(hDll, "Add");
    if (!Add) {
        std::cout << "无法找到函数 Add!" << std::endl;
        FreeLibrary(hDll);
        return -1;
    }

    // 调用函数
    int result = Add(3, 4);
    std::cout << "结果:" << result << std::endl;

    // 卸载 DLL
    FreeLibrary(hDll);
    return 0;
}

3. 特点

优点缺点
运行时动态加载,灵活使用复杂,需手动管理函数指针
可判断 DLL 是否存在,提供降级方案无编译期检查,易出错(函数名拼错)
支持插件系统、热更新、按需加载性能稍低(需查表)
程序可容忍缺失 DLL需要正确处理 FreeLibrary 防止内存泄漏

四、核心区别对比表

对比项隐式链接显式链接
加载时机程序启动时自动加载运行时手动加载(LoadLibrary)
是否需要 .lib否(可选)
函数调用方式直接调用(如 Add(1,2))通过函数指针调用
启动依赖必须存在 DLL,否则无法启动可容忍缺失,运行时报错
灵活性高(可动态选择、卸载、替换)
适用场景核心功能、稳定依赖插件、可选模块、第三方组件
错误处理启动失败可在运行时提示用户
性能略高略低(需查找符号)
典型 API无(编译器自动处理)LoadLibrary, GetProcAddress, FreeLibrary

五、如何选择?

场景推荐方式
程序核心功能依赖的 DLL(如运行库)✅ 隐式链接
第三方 SDK、硬件驱动接口✅ 显式链接(容错更好)
实现插件系统(如 Photoshop 滤镜)✅ 显式链接
需要热更新或动态替换模块✅ 显式链接
小项目、简单调用、DLL 一定存在✅ 隐式链接更方便

六、最佳实践建议

  • 优先考虑显式链接 用于第三方或可选模块,提升程序健壮性。
  • 使用 RAII 封装 HMODULE,避免忘记 FreeLibrary
class DllLoader {
public:
    DllLoader(const TCHAR* name) { hDll = LoadLibrary(name); }
    ~DllLoader() { if (hDll) FreeLibrary(hDll); }
    HMODULE get() { return hDll; }
private:
    HMODULE hDll = nullptr;
};
  • 导出 C 函数(用 extern "C")避免 C++ 名称修饰问题。
  • 在发布程序时,确保 DLL 路径正确(当前目录、系统路径、应用程序目录等)。

七、补充:如何导出 DLL 函数?

// MyDll.cpp
extern "C" __declspec(dllexport) int Add(int a, int b)
{
    return a + b;
}

extern "C" 防止 C++ 编译器名称修饰,便于 GetProcAddress 查找。

总结

方式何时用关键词
隐式链接简单、固定依赖.lib、启动加载、直接调用
显式链接灵活、容错、插件LoadLibrary、GetProcAddress、运行时加载

💬 一句话总结:

  • 简单直接 → 用 隐式链接
  • 灵活可控 → 用 显式链接

显示声明与隐式声明的使用与区别

【C++】显示声明与隐式声明的使用与区别

到此这篇关于C++中显示与隐式加载dll的使用与区别的文章就介绍到这了,更多相关C++ 显示与隐式加载dll内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++与QML进行数据交互实现方式介绍

    C++与QML进行数据交互实现方式介绍

    迫于无奈开始写android的程序,以前使用QWidget的方式试过,虽然界面可以实现,但是最后调用摄像头时,未能成功,再没有继续。这几天开始使用qml进行尝试,在使用的过程中,其中的一个难点,就是在qml与c++中数据的交互
    2022-09-09
  • C++ 名称空间详情

    C++ 名称空间详情

    当一个项目变得大型之后,我们会引入很多的库,这么一来两个库很可能会定义List、Tree、Node同名的类,编译器要是不考虑这情况的话,程序员调用时就会出现冲突问题。C++提供了名称空间工具,以更好的控制名称的作用域,本文就来谈谈C++ 名称空间,需要的朋友可以参考一下
    2021-09-09
  • 老生常谈C++ 中的继承

    老生常谈C++ 中的继承

    这篇文章主要介绍了C++ 中的继承,本文通过实例代码给大家介绍的非常详细对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • C语言实现飞机订票系统的完整代码

    C语言实现飞机订票系统的完整代码

    为了免去在窗口排队买票的麻烦,飞机订票系统应运而生,下面这篇文章主要给大家介绍了关于C语言实现飞机订票系统的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • C++超详细讲解运算符重载

    C++超详细讲解运算符重载

    本文包括了对C++类的6个默认成员函数中的赋值运算符重载和取地址和const对象取地址操作符的重载。运算符是程序中最最常见的操作,例如对于内置类型的赋值我们直接使用=赋值即可,因为这些编译器已经帮我们做好了,但是对象的赋值呢?能直接赋值吗
    2022-06-06
  • Visual Studio 2022 上使用ffmpeg的详细步骤

    Visual Studio 2022 上使用ffmpeg的详细步骤

    文章介绍了在开发项目中配置FFmpeg库的步骤,添加包含目录、库目录、依赖项及动态库路径,确保编译器和链接器正确识别FFmpeg资源,最后通过测试验证配置有效性,感兴趣的朋友一起看看吧
    2025-07-07
  • 深入分析C语言分解质因数的实现方法

    深入分析C语言分解质因数的实现方法

    这篇文章主要介绍了深入分析C语言分解质因数的实现方法,作者结合了ACM题目作为相关拓展,需要的朋友可以参考下
    2015-08-08
  • 详解C语言实现空间索引四叉树

    详解C语言实现空间索引四叉树

    本文主要介绍了用C语言实现四叉树,对算法感兴趣的同学,可以参考下,并且试验一下。
    2021-05-05
  • c语言标准库中字符转换函数和数字转换函数

    c语言标准库中字符转换函数和数字转换函数

    这篇文章主要介绍了c标准库中字符转换函数和数字转换函数,需要的朋友可以参考下
    2014-04-04
  • C++利用std::forward_list查找插入数据方法示例

    C++利用std::forward_list查找插入数据方法示例

    这篇文章主要给大家介绍了关于C++利用std::forward_list查找插入数据的相关资料,文中先对std::forward_list进行了详细的介绍,而后通过示例代码给大家介绍了查找的方法,需要的朋友可以参考借鉴,下面话不多说了,来一起看看吧。
    2017-08-08

最新评论