Linux 共享庫 (.so) 相當於 Windows DLL。優點:節省記憶體 (多程式共享同一實體)、支援動態更新、可執行檔體積較小。缺點:部署需確保庫檔案存在、版本相容性管理、啟動微小開銷。
mytestso.c
#include
#include
int GetMax(int a, int b) {
return (a >= b) ? a : b;
}
int GetInt(char* pszTxt) {
return (pszTxt == 0) ? -1 : atoi(pszTxt);
}
gcc -fPIC -shared mytestso.c -o mytestso.so
-fPIC (Position Independent Code):產生位置無關碼,共享庫必須。-shared:輸出共享物件而非執行檔。mytest.c
#include
#include
#include
int main() {
void* handle = dlopen("./mytestso.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "dlopen 失敗: %s\n", dlerror());
exit(1);
}
// 取得函式位址並轉型為函式指標
int (*GetMax)(int, int) = (int(*)(int,int)) dlsym(handle, "GetMax");
int (*GetInt)(char*) = (int(*)(char*)) dlsym(handle, "GetInt");
const char* err = dlerror();
if (err) { fprintf(stderr, "dlsym 失敗: %s\n", err); exit(1); }
printf("max=%d\n", GetMax(200, 600));
printf("txt=%d\n", GetInt("1024"));
dlclose(handle);
return 0;
}
gcc mytest.c -ldl -o mytest
-ldl:連結 libdl 提供 dlopen/dlsym/dlclose/dlerror。| 函式 | 用途 | 關鍵參數 |
|---|---|---|
dlopen | 載入共享庫 | 路徑、旗標: RTLD_LAZY (延遲解析) / RTLD_NOW (立即解析) |
dlsym | 取得符號 (函式/變數) 位址 | Handle、符號名稱字串 |
dlerror | 取得最後錯誤訊息 | 無參數,呼叫後清除錯誤狀態 |
dlclose | 卸載共享庫 | Handle,參考計數歸零時真正卸載 |
LD_LIBRARY_PATH 指定的目錄/etc/ld.so.cache 快取 (由 ldconfig 維護)/usr/lib, /lib./)建議安裝至標準目錄並執行 ldconfig,或設定 rpath 連結選項。
libfoo.so.1.0 → libfoo.so.1 (soname) → libfoo.so (linker name)。-fvisibility=hidden 預設隱藏,配合 __attribute__((visibility("default"))) 匯出公共 API。__attribute__((constructor)) / (destructor) 在載入/卸載時自動執行。extern "C" 避免修飾,或使用 c++filt 解碼。