UNIX 动态库和静态库
動態庫,又叫做共享對象庫,以.so結尾。使用動態庫時,編譯器并不直接在編譯的時候將代碼嵌入到目標文件中,而是等到運行時調用相應的函數,才加載代碼。
? ? ? ?靜態庫,又叫做歸檔文件,以.a結尾。使用靜態庫的時候,編譯器在編譯過程中直接將代碼嵌入到目標文件中,所以一旦完成編譯,那么靜態庫可以不需要了。
1、編寫靜態庫以及使用靜態庫
首先編寫hello.h文件。
然后編寫hello.c文件。
然后編寫main.c。
我們使用gcc -c hello.c得到二進制目標文件hello.o,然后使用ar命令生成靜態鏈接庫libhello.a。
ar -cru libhello.a hello.o
指定鏈接庫對main.c進行編譯鏈接生成可執行文件main.out
gcc -o main.out -L. -lhello main.c
執行main.out文件得到結果:
這樣就完成從編寫靜態鏈接庫到使用靜態庫的全部過程。
2、編寫動態庫并且使用動態庫
現在我們來完成動態鏈接庫的編寫。
還是上面的hello.h hello.c main.c文件,我們生成動態鏈接庫libhello.so。
使用命令gcc -c hello.c -fPIC生成hello.o目標文件,使用gcc -shared將hello.o加入到動態庫libhello.so中,
gcc -shared hello.o -o libhello.so
編譯鏈接main.c
gcc main.c -o main.out -L. -lhello
配置LD_LIBRARY_PATH的內容包含當前目錄:
export LD_LIBRARY_PATH=/usr/local/lib :.執行main.out得到下面的運行情況。
三、程序中顯式加載動態庫
? ? ? ?還是按照前面的步驟,生成動態庫libhello.so,然后在main.c程序中顯式的加載動態庫,具體見代碼:
? ? ? ? 使用gcc -ldl main.c -o main.out生成可執行程序。執行main.out的時候也需要尋找動態庫的路徑中包含當前目錄,也就是同樣使用export LD_LIBRARY_PATH=.。然后執行可執行程序得到的結果與2中的結果相同。
void *dlopen(const char *filename, int flag);
其中flag有:RTLD_LAZY RTLD_NOW RTLD_GLOBAL,其含義分別為:
RTLD_LAZY:在dlopen返回前,對于動態庫中存在的未定義的變量(如外部變量extern,也可以是函數)不執行解析,就是不解析這個變量的地址。
RTLD_NOW:與上面不同,他需要在dlopen返回前,解析出每個未定義變量的地址,如果解析不出來,在dlopen會返回NULL,錯誤為:
: undefined symbol: xxxx.......
RTLD_GLOBAL:它的含義是使得庫中的解析的定義變量在隨后的其它的鏈接庫中變得可以使用。
總結
以上是生活随笔為你收集整理的UNIX 动态库和静态库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Eclipse CDT Hello Wo
- 下一篇: gdb调试命令的使用及总结