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语言函数调用底层实现原理分析

    C语言函数调用底层实现原理分析

    这篇文章主要介绍了C语言函数调用底层实现原理,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C++迭代器失效问题及解决

    C++迭代器失效问题及解决

    这篇文章主要介绍了C++迭代器失效问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C语言实现文件读写

    C语言实现文件读写

    这篇文章主要为大家详细介绍了C语言实现文件读写,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • c++中stoi函数的使用小结

    c++中stoi函数的使用小结

    本文主要介绍了c++中stoi函数的使用小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-02-02
  • C++深入探究引用的本质与意义

    C++深入探究引用的本质与意义

    引用是C++一个很重要的特性,顾名思义是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作完全等价,这篇文章主要给大家总结介绍了C++中引用的相关知识点,需要的朋友可以参考下
    2022-04-04
  • C++实现LeetCode(7.翻转整数)

    C++实现LeetCode(7.翻转整数)

    这篇文章主要介绍了C++实现LeetCode(7.翻转整数),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C语言与JAVA的区别是什么(推荐)

    C语言与JAVA的区别是什么(推荐)

    本文是小编给大家收集整理的关于C语言与Java的区别介绍,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-04-04
  • C++中整形与浮点型如何在内存中的存储详解

    C++中整形与浮点型如何在内存中的存储详解

    大家好!这期和大家分享整形和浮点型是如何在数据是如何在内存中存储,下面文章具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • 教你如何使用C++ 统计地铁中站名出现的字的个数

    教你如何使用C++ 统计地铁中站名出现的字的个数

    通过本文教大家如何使用C++ 统计地铁中站名出现的字的个数,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2022-01-01
  • C语言进阶数据的存储机制完整版

    C语言进阶数据的存储机制完整版

    这篇文章主要为大家完整的介绍了C语言进阶数据的存储机制,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-02-02

最新评论