当前位置: 代码网 > it编程>编程语言>C/C++ > C++中显示与隐式加载dll的使用与区别

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

2025年12月19日 C/C++ 我要评论
一、什么是 dll?dll(dynamic link library) 是 windows 下的动态链接库,包含可被多个程序共享的函数、资源或类。使用 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内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com