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

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











