C++如何加载和调用动态链接库(DLL/SO)?(代码示例)


C++动态加载DLL/SO需运行时调用系统API:Windows用LoadLibrary/GetProcAddress,Linux用dlopen/dlsym;均需显式类型转换函数指针、正确导出符号(extern "C" __declspec(dllexport))、配对卸载,并注意路径、位数及签名匹配。

C++ 加载和调用动态链接库(Windows 的 DLL 或 Linux 的 SO)主要靠运行时动态加载机制:Windows 用 LoadLibrary / GetProcAddress,Linux 用 dlopen / dlsym。核心思路是——不链接 .lib/.a,而是在程序运行时打开库文件,手动获取函数地址并调用。

Windows 下加载 DLL(使用 WinAPI)

需包含 ,确保 DLL 文件在可搜索路径(如当前目录、系统路径或 PATH 中)。

  • LoadLibrary 打开 DLL,返回模块句柄(HMODULE
  • GetProcAddress 根据函数名获取函数指针,注意类型强转
  • 调用完成后用 FreeLibrary 卸载(非必须,但推荐)

示例(假设 DLL 中导出一个 int add(int, int) 函数):

#include 
#include 

typedef int (*AddFunc)(int, int);

int main() { HMODULE hDll = LoadLibrary(L"mylib.dll"); if (!hDll) { std::cerr << "Failed to load DLL\n"; return -1; }

AddFunc add = (AddFunc)GetProcAddress(hDll, "add");
if (!add) {
    std::cerr << "Failed to get function address\n";
    FreeLibrary(hDll);
    return -1;
}

std::cout << "Result: " << add(3, 5) << "\n"; // 输出 8

FreeLibrary(hDll);
return 0;

}

⚠️ 注意:DLL 中的函数需用 extern "C" __declspec(dllexport) 导出,避免 C++ 名字修饰干扰;若用 C++ 成员函数或重载函数,需额外封装为 C 风格接口。

Linux 下加载 SO(使用 libdl)

需链接 -ldl,头文件为 ,SO 文件路径支持相对或绝对路径(如 "./libmylib.so")。

  • dlopen 打开共享库,返回 void* 句柄
  • dlsym 获取符号地址,同样需显式类型转换
  • 出错时用 dlerror() 获取错误信息
  • dlclose 卸载(非强制,但建议配对使用)

示例(对应同一 add 函数):

#include 
#include 

typedef int (*AddFunc)(int, int);

int main() { void* handle = dlopen("./libmylib.so", RTLD_LAZY); if (!handle) { std::cerr << "dlopen failed: " << dlerror() << "\n"; return -1; }

AddFunc add = (AddFunc)dlsym(handle, "add");
const char* error = dlerror();
if (error) {
    std::cerr << "dlsym failed: " << error << "\n";
    dlclose(handle);
    return -1;
}

std::cout << "Result: " << add(3, 5) << "\n";

dlclose(handle);
return 0;

}

⚠️ 编译命令:g++ main.cpp -ldl -o main;SO 文件需已存在且有执行权限(通常默认满足)。

跨平台封装小技巧(简化调用)

为减少重复判断,可封装一个轻量类或宏。例如定义统一的句柄类型:

#ifdef _WIN32
    #include 
    using LibHandle = HMODULE;
    #define LOAD_LIB(name) LoadLibrary(TEXT(name))
    #define GET_PROC(h, name) GetProcAddress((h), (name))
    #define FREE_LIB(h) FreeLibrary(h)
#else
    #include 
    using LibHandle = void*;
    #define LOAD_LIB(name) dlopen((name), RTLD_LAZY)
    #define GET_PROC(h, name) dlsym((h), (name))
    #define FREE_LIB(h) dlclose(h)
#endif

后续代码只需操作 LibHandle 和统一宏,逻辑更清晰。实际项目中也可用 CMake 的 find_librarytarget_link_libraries 配合 IMPORTED 目标做更高级管理。

常见问题与避坑点

  • DLL/SO 文件未找到:检查路径、拼写、位数匹配(32/64 位程序只能加载同位数库)
  • 函数找不到:确认导出符号名正确(可用 dumpbin /exports(Win)或 nm -D(Linux)查看)
  • 调用崩溃:函数签名不匹配(参数/返回值类型或调用约定错误),务必 typedef 显式声明
  • 内存泄漏风险:每次 LoadLibrary/dlopen 应配对 FreeLibrary/dlclose,尤其在循环或插件系统中

不复杂但容易忽略细节,关键是把“加载→查符号→转类型→调用→卸载”这五步走稳。


# linux  # windows  # cad  # ai  # c++  # ios  # win  # stream  # 常见问题  # typedef  # lsp  # 封装  # 成员函数  # extern  # int  # void  # 循环  # 指针  # 重载函数  # 接口  # 值类型  # 类型转换  # 加载  # 句柄  # 是在  # 找不到  # 只需  # 中也  # 错误信息  # 时用  # 小技巧  # 高级管理 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: Windows10怎么用“讲述人”读屏辅助 Windows10轻松使用开启讲述人朗读屏幕文字帮助视障用户【教程】  Windows系统被恶意软件破坏后的恢复策略_错误提示修复方式  PHP主流架构怎么处理表单验证_规则与自定义【技巧】  如何测试您的网站全球打开速度-网站海外测速工  c++ reinterpret_cast怎么用 c++最危险的类型转换【详解】  Python文本编码与解码_跨平台解析说明【指导】  C++中的协变与逆变是什么?C++函数指针与返回类型详解【类型系统】  Win11蓝牙开关不见了怎么办_Win11蓝牙驱动丢失修复教程【方法】  Windows7如何安装系统镜像_Windows7系统安装教程【步骤】  Win10系统更新错误0x80240034怎么办 Win10更新错误解决法【方法】  Win11如何开启telnet服务 Win11启用Telnet客户端【步骤】  Win11无法拖拽文件到任务栏怎么办_Win11开启拖放功能修复【方法】  c++的STL算法库find怎么用 在容器中查找指定元素【实用教程】  如何在Windows中创建新的用户账户?(标准与管理员)  PythonGIL机制理解_多线程限制解析【教程】  php查询数据怎么导出csv_查询结果转csv文件保存【操作】  如何在 Go 项目开发中正确处理本地包导入与远程模块路径的一致性问题  Win11怎么关闭搜索历史 Win11清除搜索框最近记录【隐私】  Windows10系统怎么查看系统版本_Win10运行winver命令查询  Win11怎么关闭自动调节亮度 Win11禁用内容自适应亮度【设置】  mac怎么退出id_MAC退出iCloud账号与Apple ID切换【指南】  MAC怎么用连续互通相机里的“桌上视角”_MAC在视频通话中同时展示人脸和桌面  Windows10蓝屏代码DPC_WATCHDOG_VIOLATION_Win10死机修复指南  Windows10如何更改任务栏高度_Win10解除锁定调整大小  如何在 Django 中修改用户密码后保持会话不丢失  Python音视频处理高级项目教程_FFmpegPydub剪辑与特效  Win11怎样安装剪映专业版_Win11安装剪映教程【步骤】  Win11快速助手怎么用_Win11远程协助连接教程【工具】  Mac的“调度中心”与“空间”怎么用_Mac多桌面高效管理【技巧】  Python代码测试策略_质量保障解析【教程】  如何在Golang中实现文件下载_Golang文件传输与内容类型处理方法  Windows10电脑怎么设置自动连接WiFi_Win10无线网络属性勾选  Win11怎么设置闹钟_Windows 11时钟应用闹钟设置指南【详解】  Python多进程教程_multiprocessing模块实战  如何使用Golang实现错误包装与传递_Golangfmt.Errorf%w使用实践  Win11如何设置自动关机 Win11定时关机命令使用教程【技巧】  Windows10怎么查看硬件信息_Windows10硬件信息查询方法【指南】  Win11怎么设置默认PDF阅读器 Win11修改PDF打开方式【步骤】  如何在 Go 结构体中正确初始化 map 字段  php订单日志权限怎么设_php订单日志文件权限设置技巧【技巧】  Win11怎么连接投影仪_Win11多显示器投屏设置指南【步骤】  Win10文件历史记录怎么用 Win10开启自动备份文件教程【防丢】  Win11怎么查看局域网电脑_Windows 11网络邻居发现设置【技巧】  c++获取当前时间戳_c++ time函数使用详解  如何在Golang中编写异步函数测试_Golang异步操作测试策略  Mac如何将HEIC图片格式转为JPG_Mac批量转换图片【指南】  Windows怎样拦截WPS弹窗广告_Windows拦截WPS弹窗广告设置【步骤】  Python lxml的etree和ElementTree有什么区别  Windows10怎么查看系统激活状态_Windows10激活状态查看方法【教程】  windows系统如何安装cab更新补丁_windows手动安装更新包教程 

 2026-01-04

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.