C++中通过操作系统API实现运行时动态加载库,Linux使用dlopen/dlsym/dlclose配合加载.so文件,Windows使用LoadLibrary/GetProcAddress/FreeLibrary配合加载.dll文件,需注意函数导出方式为extern "C"以避免名称修饰,同时应正确处理路径、错误检查与资源释放,跨平台时可封装统一接口提升可移植性。

在C++中实现运行时动态加载库,可以使用操作系统提供的API:Linux下用dlopen系列函数,Windows下用LoadLibrary相关函数。这种方式允许程序在运行时按需加载共享库(如.so或.dll),调用其中的函数,提升模块化和灵活性。
Linux 下使用 dlopen / dlsym / dlclose
在类Unix系统中,动态加载库依赖于dl库。需要包含头文件。
基本步骤:
- 用
dlopen打开共享库文件(.so) - 用
dlsym获取函数或变量地址 - 用完后用
dlclose关闭库
示例代码:
立即学习“C++免费学习笔记(深入)”;
#include#include int main() { void* handle = dlopen("./libmath.so", RTLD_LAZY); if (!handle) { std::cerr << "无法加载库: " << dlerror() << '\n'; return 1; }
// 获取函数指针 double (*add)(double, double) = (double(*)(double, double))dlsym(handle, "add"); const char* error = dlerror(); if (error) { std::cerr zuojiankuohaophpcnzuojiankuohaophpcn "无法找到函数: " zuojiankuohaophpcnzuojiankuohaophpcn error zuojiankuohaophpcnzuojiankuohaophpcn '\n'; dlclose(handle); return 1; } std::cout zuojiankuohaophpcnzuojiankuohaophpcn "调用 add(3.5, 4.2): " zuojiankuohaophpcnzuojiankuohaophpcn add(3.5, 4.2) zuojiankuohaophpcnzuojiankuohaophpcn '\n'; dlclose(handle); return 0;}
编译注意:链接-ldl,例如:
Windows 下使用 LoadLibrary / GetProcAddress / FreeLibrary
Windows平台使用Win32 API,需包含。
基本流程:
- 用
LoadLibrary加载DLL - 用
GetProcAddress获取导出函数地址 - 用
FreeLibrary释放库
示例代码:
立即学习“C++免费学习笔记(深入)”;
#include#include int main() { HINSTANCE hLib = LoadLibrary(L"math.dll"); if (!hLib) { std::wcerr << L"无法加载DLL\n"; return 1; }
// 定义函数类型 typedef double (*AddFunc)(double, double); AddFunc add = (AddFunc)GetProcAddress(hLib, "add"); if (!add) { std::cerr zuojiankuohaophpcnzuojiankuohaophpcn "无法找到函数 add\n"; FreeLibrary(hLib); return 1; } std::cout zuojiankuohaophpcnzuojiankuohaophpcn "调用 add(3.5, 4.2): " zuojiankuohaophpcnzuojiankuohaophpcn add(3.5, 4.2) zuojiankuohaophpcnzuojiankuohaophpcn '\n'; FreeLibrary(hLib); return 0;}
跨平台封装建议
为便于移植,可封装统一接口:
#ifdef _WIN32 #includeusing LibHandle = HMODULE; #else #include using LibHandle = void*; #endif LibHandle load_library(const char* path) {
ifdef _WIN32
return LoadLibraryA(path);else
return dlopen(path, RTLD_LAZY);endif
}
void get_symbol(LibHandle lib, const char name) {
ifdef _WIN32
return GetProcAddress(lib, name);else
return dlsym(lib, name);endif
}
void close_library(LibHandle lib) {
ifdef _WIN32
FreeLibrary(lib);else
dlclose(lib);endif
}
注意事项
- 确保库文件路径正确,相对或绝对路径均可
- 函数必须以C方式导出(避免C++名称修饰),在共享库中使用
extern "C" - 检查返回值和错误(
dlerror或 GetLastError) - 管理好资源,防止内存泄漏或重复加载
基本上就这些。动态加载库在插件系统、热更新等场景非常实用。










