Linux 共用函式庫 (Shared Object, .so) 相當於 Windows 的 DLL,實現程式碼重用、模組化部署與記憶體共享。本文詳述建立流程、動態載入機制、關鍵 API 與完整範例。
#include <stdio.h>
#include <stdlib.h>
int GetMax(int a, int b) {
return (a >= b) ? a : b;
}
int GetInt(const char* psztxt) {
if (!psztxt) return -1;
return atoi(psztxt);
}
gcc -fPIC -shared mytestso.c -o mytestso.so
| 參數 | 說明 |
|---|---|
-fPIC | 產生位置無關碼 (Position Independent Code),支援共用記憶體映射 |
-shared | 輸出共用函式庫而非執行檔 |
-o mytestso.so | 輸出檔名 |
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
void* handle;
char* error;
int (*GetMax)(int, int);
int (*GetInt)(const char*);
int a = 200, b = 600;
const char* txt = "1024";
// 1. 開啟共用函式庫
handle = dlopen("./mytestso.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(1);
}
// 2. 取得函數位址
GetMax = (int(*)(int,int)) dlsym(handle, "GetMax");
if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(1); }
GetInt = (int(*)(const char*)) dlsym(handle, "GetInt");
if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(1); }
// 3. 呼叫函數
printf("max=%d\n", GetMax(a, b));
printf("txt=%d\n", GetInt(txt));
// 4. 關閉
dlclose(handle);
return 0;
}
gcc mytest.c -ldl -o mytest
-ldl:連結 libdl,提供 dlopen 等 API| 參數 | 說明 |
|---|---|
| filename | 函式庫路徑。搜尋順序: ① 環境變數 LD_LIBRARY_PATH② /etc/ld.so.cache (由 ldconfig 維護)③ /usr/lib, /lib④ 當前目錄 (需 ./ 前綴) |
| flags | RTLD_LAZY:延遲解析符號 (預設,效能較好)RTLD_NOW:立即解析所有符號 (利於除錯) |
dlerror() 檢查dlopen/dlsym/dlclose 的錯誤訊息,僅能呼叫一次 (第二次回傳 NULL)// 函式庫載入時自動執行
__attribute__((constructor)) void MyLibInit() {
printf("Library loaded\n");
}
// 函式庫卸載時自動執行
__attribute__((destructor)) void MyLibFini() {
printf("Library unloaded\n");
}
# 建立帶版本的庫
gcc -fPIC -shared -Wl,-soname,libmylib.so.1 mylib.c -o libmylib.so.1.0
# 建立連結
ln -sf libmylib.so.1.0 libmylib.so.1
ln -sf libmylib.so.1 libmylib.so
// 隱藏內部符號 (GCC 4+)
__attribute__((visibility("hidden"))) void InternalFunc();
// 只匯出標記的符號
// 編譯加 -fvisibility=hidden,公開函數加 __attribute__((visibility("default")))
extern "C" 避免名稱修飾:extern "C" int GetMax(int, int);LD_DEBUG=libs ./mytest:顯示動態連結器載入過程ldd mytest:檢查相依函式庫解析狀況nm -D mytestso.so:列出匯出符號set solib-search-path 設定符號檔路徑Linux 共用函式庫機制成熟靈活,掌握 dlopen/dlsym/dlclose 動態載入流程、-fPIC 編譯要點、版本管理與符號可見性控制,能構建模組化、可擴充的系統架構。現代專案建議搭配 CMake 管理建構流程,自動處理平台差異。