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

在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 #include 

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

int main() {HMODULE lib = LoadLibrary(L"example.dll");if (!lib) {std::cerr << "无法加载DLL" << std::endl;return -1;}

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

#include #include 

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

int main() {void* lib = dlopen("./libexample.so", RTLD_LAZY);if (!lib) {std::cerr << "无法加载SO: " << dlerror() << std::endl;return -1;}

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     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     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

class DynamicLib {public:explicit DynamicLib(const char* path) {handle = LOAD_LIB(path);}

~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.soif (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++跨平台动态链接库加载方法的详细内容,更多请关注创想鸟其它相关文章!

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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月19日 07:47:22
下一篇 2025年12月19日 07:47:34

相关推荐

发表回复

登录后才能评论
关注微信