動態(tài)加載共享庫需按平臺使用dlopen/dlsym或LoadLibrary/GetProcAddress,通過extern "C"導(dǎo)出函數(shù)避免命名修飾,封裝跨平臺接口可提升代碼復(fù)用性,完整流程包括加載庫、獲取函數(shù)指針、調(diào)用及釋放資源。
在C++中動態(tài)加載和使用共享庫(Linux下的.so文件或Windows下的DLL)是一種常見的運行時模塊化編程技術(shù)。它允許程序在運行時按需加載庫并調(diào)用其中的函數(shù),適用于插件系統(tǒng)、熱更新等場景。
動態(tài)加載的核心是通過操作系統(tǒng)提供的API來打開庫文件、獲取函數(shù)地址,并在使用完畢后釋放資源。不同平臺的接口不同:
為了跨平臺兼容,通常會使用宏定義封裝這些差異。
假設(shè)有一個名為 libmathplugin.so 的共享庫,導(dǎo)出一個函數(shù):
立即學(xué)習(xí)“C++免費學(xué)習(xí)筆記(深入)”;
// mathfunc.h extern "C" double add(double a, double b);
在主程序中動態(tài)加載該庫:
#include <dlfcn.h> #include <iostream> <p>int main() { void* handle = dlopen("./libmathplugin.so", RTLD_LAZY); if (!handle) { std::cerr << "無法加載庫: " << dlerror() << '\n'; return 1; }</p><pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">// 獲取函數(shù)指針 using AddFunc = double(*)(double, double); AddFunc add_func = (AddFunc)dlsym(handle, "add"); const char* error = dlerror(); if (error) { std::cerr << "無法找到函數(shù): " << error << '\n'; dlclose(handle); return 1; } // 調(diào)用函數(shù) std::cout << "結(jié)果: " << add_func(3.5, 2.5) << '\n'; dlclose(handle); return 0;
}
編譯時需要鏈接 dl 庫:
g++ main.cpp -ldl
對于DLL,假設(shè)導(dǎo)出了相同的 add 函數(shù):
// DLL中的導(dǎo)出聲明(mathfunc.h) extern "C" __declspec(dllexport) double add(double a, double b);
主程序加載DLL:
#include <windows.h> #include <iostream> <p>int main() { HMODULE handle = LoadLibrary(L"mathplugin.dll"); if (!handle) { std::cerr << "無法加載DLL\n"; return 1; }</p><pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">using AddFunc = double(*)(double, double); AddFunc add_func = (AddFunc)GetProcAddress(handle, "add"); if (!add_func) { std::cerr << "無法找到函數(shù)\n"; FreeLibrary(handle); return 1; } std::cout << "結(jié)果: " << add_func(3.5, 2.5) << '\n'; FreeLibrary(handle); return 0;
}
可以定義統(tǒng)一接口簡化使用:
#ifdef _WIN32 #include <windows.h> using LibHandle = HMODULE; #define load_lib(name) LoadLibraryA(name) #define get_func(lib, func) GetProcAddress(lib, func) #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, func) dlsym(lib, func) #define free_lib(lib) dlclose(lib) #endif
這樣主邏輯可保持一致:
LibHandle handle = load_lib("myplugin.dll"); if (handle) { auto func = (FuncType)get_func(handle, "function_name"); if (func) func(); free_lib(handle); }
基本上就這些。關(guān)鍵是確保函數(shù)以 extern "C" 導(dǎo)出避免C++命名修飾,同時注意路徑、權(quán)限和錯誤處理。實際項目中還可結(jié)合配置文件或插件注冊機制實現(xiàn)更靈活的加載策略。
以上就是c++++中如何動態(tài)加載和使用so/dll庫_c++動態(tài)庫加載與調(diào)用函數(shù)方法的詳細內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
.dll文件缺失怎么辦?.dll文件在哪下載?不用擔(dān)心,這里為大家提供了所有的.dll文件下載,無論用戶丟失的是什么.dll文件,在這里都能找到。用戶保存后,在網(wǎng)盤搜索dll文件全稱即可查找下載!
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號