首页 > 后端开发 > C++ > 正文

c++怎么在运行时动态加载库(dll/so)_c++跨平台动态链接库加载方法

裘德小鎮的故事
发布: 2025-11-14 21:44:50
原创
187人浏览过
在C++中通过封装LoadLibrary/GetProcAddress和dlopen/dlsym实现跨平台动态库加载,Windows使用HMODULE,Linux/Unix使用void*,统一接口支持插件系统。

c++怎么在运行时动态加载库(dll/so)_c++跨平台动态链接库加载方法

在C++中实现运行时动态加载库(Windows下的DLL和Linux/Unix下的SO)是一项常见的跨平台需求,比如插件系统或模块化架构。虽然不同操作系统提供的API不同,但可以通过封装统一接口来实现跨平台兼容。

Windows: 使用 LoadLibrary 和 GetProcAddress

在Windows平台上,使用 LoadLibrary(或 LoadLibraryEx)加载DLL,用 GetProcAddress 获取函数地址,FreeLibrary 释放库。

示例代码:

#include <windows.h>
#include <iostream>
<p>typedef int (*AddFunc)(int, int);</p><p>int main() {
HMODULE lib = LoadLibrary(L"example.dll");
if (!lib) {
std::cerr << "无法加载DLL" << std::endl;
return -1;
}</p><pre class='brush:php;toolbar:false;'>AddFunc add = (AddFunc)GetProcAddress(lib, "add");
if (!add) {
    std::cerr << "无法获取函数地址" << std::endl;
    FreeLibrary(lib);
    return -1;
}

std::cout << "结果: " << add(2, 3) << std::endl;

FreeLibrary(lib);
return 0;
登录后复制

}

立即学习C++免费学习笔记(深入)”;

Linux/Unix: 使用 dlopen 和 dlsym

在类Unix系统中,通过 dlopen 加载共享库(.so),dlsym 获取符号地址,dlclose 释放库。

编译时需链接 dl 库:-ldl

度加剪辑
度加剪辑

度加剪辑(原度咔剪辑),百度旗下AI创作工具

度加剪辑 63
查看详情 度加剪辑
#include <dlfcn.h>
#include <iostream>
<p>typedef int (*AddFunc)(int, int);</p><p>int main() {
void* lib = dlopen("./libexample.so", RTLD_LAZY);
if (!lib) {
std::cerr << "无法加载SO: " << dlerror() << std::endl;
return -1;
}</p><pre class='brush:php;toolbar:false;'>AddFunc add = (AddFunc)dlsym(lib, "add");
const char* error = dlerror();
if (error) {
    std::cerr << "无法获取函数: " << error << std::endl;
    dlclose(lib);
    return -1;
}

std::cout << "结果: " << add(2, 3) << std::endl;

dlclose(lib);
return 0;
登录后复制

}

立即学习C++免费学习笔记(深入)”;

跨平台封装示例

为了实现跨平台,可以封装一个简单的动态库加载类:

#ifdef _WIN32
    #include <windows.h>
    using LibHandle = HMODULE;
    #define LOAD_LIB(name) LoadLibraryA(name)
    #define GET_FUNC(lib, name) GetProcAddress(lib, name)
    #define FREE_LIB(lib) FreeLibrary(lib)
#else
    #include <dlfcn.h>
    using LibHandle = void*;
    #define LOAD_LIB(name) dlopen(name, RTLD_LAZY)
    #define GET_FUNC(lib, name) dlsym(lib, name)
    #define FREE_LIB(lib) dlclose(lib)
#endif
<p>class DynamicLib {
public:
explicit DynamicLib(const char* path) {
handle = LOAD_LIB(path);
}</p><pre class='brush:php;toolbar:false;'>~DynamicLib() {
    if (handle) FREE_LIB(handle);
}

void* getFunction(const char* name) {
    return GET_FUNC(handle, name);
}

bool isValid() const { return handle != nullptr; }
登录后复制

private: LibHandle handle = nullptr; };

使用方式:

DynamicLib lib("example.dll"); // 或 libexample.so
if (lib.isValid()) {
    auto add = (AddFunc)lib.getFunction("add");
    if (add) std::cout << add(2, 3) << std::endl;
}
登录后复制

注意事项与建议

  • C++存在函数名修饰(name mangling),推荐在导出函数前加上 extern "C" 防止重命名,确保符号可被正确查找。
  • 确保库的路径正确,相对路径可能因工作目录不同而失败,建议使用绝对路径。
  • 加载失败时及时处理错误(Windows用GetLastError,Linux用dlerror)。
  • 注意库的依赖关系,目标机器需具备运行所需的所有依赖库。
  • 跨平台构建时,可用CMake统一管理不同平台的编译规则。

基本上就这些。只要封装好平台差异,并规范导出接口,C++动态加载库并不复杂,但容易忽略细节导致运行失败。

以上就是c++++怎么在运行时动态加载库(dll/so)_c++跨平台动态链接库加载方法的详细内容,更多请关注php中文网其它相关文章!

.dll文件大全
.dll文件大全

.dll文件缺失怎么办?.dll文件在哪下载?不用担心,这里为大家提供了所有的.dll文件下载,无论用户丢失的是什么.dll文件,在这里都能找到。用户保存后,在网盘搜索dll文件全称即可查找下载!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号