linux動態庫的初始化和清理
a. Windows 中有 DllMain 入口函式, 而 Linux 中則沒有。
b. Linux 中有特殊函式 _init 和 _fini, 主要是分別用來初始化動態庫和關閉的時候
做一些必要的處理, 我們可以把自己認為需要的程式碼放到這兩個函式裡面, 它們分別
在動態庫被載入和釋放的時候被執行。具體說, 如果一個動態庫裡面有一個名字為
"_init" 的函式輸出, 那麼在第一次通過 dlopen() 函式開啟這個動態庫, 或者只是
簡單的作為共享動態庫被開啟的時候, _init 函式被自動呼叫執行。與之相對應的就
是 _fini 函式, 當一個程式呼叫 dlclose() 去釋放對這個動態
果該動態庫的被引用計數器為 0 了, 或者這個動態庫是作為一般的共享動態庫被使
用而使用它的程式正常退出的時候, _fini就會被呼叫執行。
C語言定義它們的原型如下:
void _init(void);
void _fini(void);
當使用你自己的 _init 和 _fini 函式時, 會出現命名衝突, 就會得到一個
"multiple-definition" 的錯誤, 編譯器提示已經存在這個名字, 可以通過幾種方式
來解決:
1). 自定義 init 函式名字, 比如 myinit 用 -Wl, 選項給 ld 傳遞此名字:
gcc ... -Wl,-init=myinit
2). 當 GCC 編譯源程式時, 可以使用選項 -nostartfiles 來使共享庫不與系統
啟動檔案一起編譯
gcc ... -nostartfiles
3). 使用上面的函式或 GCC 的 -nostartfiles 選項並不是很好的習慣, 因為這
可能會產生一些意外的結果。相反, 庫應該使用
__attribute__((constructor)) 和 __attribute__((destructor)) 函式屬
性來輸出它的建構函式和解構函式。如下所示:
void __attribute__((constructor)) x_init(void);
void __attribute__((destructor)) x_fini(void);
建構函式會在dlopen()返回前或庫被裝載時呼叫;
解構函式會在這樣幾種情況下被呼叫: dlclose() 返回前, 或 main() 返回
後, 或裝載庫過程中 exit() 被呼叫時。
c. Linux 中的初始化和釋放函式不建議使用。