動態編譯和靜態編譯,共享庫

簡介

靜態函數庫函數

通常擴展名爲(.a),這類的函數庫一般擴展名爲libxxx.a 。
這類函數庫在編譯的時候會直接整合到程序中,因此利用靜態函數庫編譯成的文件會比較大,這類函數庫最大的優勢就是編譯成功的可執行文件能夠獨立運行,而再也不須要向外部要求讀取函數庫的內容;可是從升級難易度來看明顯沒有優點,若是函數庫更新,須要從新編譯。測試

動態函數庫code

動態函數庫的擴展名通常爲(.so),這類函數庫一般名爲libxxx.so 。
與靜態函數庫被整個捕捉到程序中不一樣,動態函數庫在編譯的時候,在程序裏只有一個「指向」的位置而已,也就是說當可執行文件須要使用到函數庫的機制時,程序纔會去讀取函數庫來使用;也就是說可執行文件沒法單獨運行。通常,在程序第一次執行或者第一次調用的時候,可能會在加載連接庫的時候慢點,但這樣減小看每一個可執行文件的長度, 並且其餘的程序若是發現內存中已經存在這個連接庫的時候就不須要再次加載了。 另外,使用共享庫的可使用庫函數來迭代更新,應用程序將無需更改,只要函數的接口不變。接口

例子

第1步:編輯獲得舉例的程序hello.h、hello.c和main.c;內存

hello.h (見程序1)爲該函數庫的頭文件。
hello.c (見程序2)是函數庫的源程序,其中包含公用函數hello,該函數將在屏幕上輸出"Hello XXX!"。
main.c (見程序3)爲測試庫文件的主程序,在主程序中調用了公用函數hello。rem

--------------------------------------------------------------------------------  
 程序1: hello.h  
#ifndef HELLO_H  
#define HELLO_H  
void hello(const char *name);  
#endif //HELLO_H  
--------------------------------------------------------------------------------  
 程序2: hello.c  
 
#include <stdio.h>
void hello(const char *name)  
{  
    printf("Hello %s!\n", name);  
}  
--------------------------------------------------------------------------------  
 程序3: main.c  
#include "hello.h"  
int main()  
{  
    hello("everyone");  
    return 0;  
}  
--------------------------------------------------------------------------------

第2步:將hello.c編譯成.o文件原型

在系統提示符下鍵入如下命令獲得hello.o文件。io

# gcc -c hello.c

第3步:由.o文件建立靜態庫編譯

靜態庫文件名的命名規範是以lib爲前綴,緊接着跟靜態庫名,擴展名爲.a。例如:咱們將建立的靜態庫名爲myhello,則靜態庫文件名就是libmyhello.a。在建立和使用靜態庫時,須要注意這點。建立靜態庫用ar命令。在系統提示符下鍵入如下命令將建立靜態庫文件libmyhello.a。gcc

# ar cr libmyhello.a hello.o

第4步:在程序中使用靜態庫

靜態庫製做完了,如何使用它內部的函數呢?只須要在使用到這些公用函數的源程序中包含這些公用函數的原型聲明,而後在用gcc命令生成目標文件時指明靜態庫名,gcc將會從靜態庫中將公用函數鏈接到目標文件中。注意,gcc會在靜態庫名前加上前綴lib,而後追加擴展名.a獲得的靜態庫文件名來查找靜態庫文件。在程序3:main.c中,咱們包含了靜態庫的頭文件hello.h,而後在主程序main中直接調用公用函數hello。下面先生成目標程序hello,而後運行hello程序看看結果如何。

# gcc -o hello main.c -L. -lmyhello
# ./hello
Hello everyone!

咱們刪除靜態庫文件試試公用函數hello是否真的鏈接到目標文件 hello中了。

# rm libmyhello.a
rm: remove regular file `libmyhello.a'? y
# ./hello
Hello everyone!

程序照常運行,靜態庫中的公用函數已經鏈接到目標文件中了。咱們繼續看看如何在Linux中建立動態庫。咱們仍是從.o文件開始。

第5步:由.o文件建立動態庫文件

動態庫文件名命名規範和靜態庫文件名命名規範相似,也是在動態庫名增長前綴lib,但其文件擴展名爲.so。例如:咱們將建立的動態庫名爲myhello,則動態庫文件名就是libmyhello.so。用gcc來建立動態庫。在系統提示符下鍵入如下命令獲得動態庫文件libmyhello.so。

# gcc hello.c -fPIC  -shared -o libmyhello.so

第6步:在程序中使用動態庫

在程序中使用動態庫和使用靜態庫徹底同樣,也是在使用到這些公用函數的源程序中包含這些公用函數的原型聲明,而後在用gcc命令生成目標文件時指明動態庫名進行編譯。咱們先運行gcc命令生成目標文件,再運行它看看結果。

# gcc -o hello main.c -L. -lmyhello
# ./hello
./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory

哦!出錯了。快看看錯誤提示,原來是找不到動態庫文件libmyhello.so。程序在運行時,會在/usr/lib64和/lib等目錄中查找須要的動態庫文件。若找到,則載入動態庫,不然將提示相似上述錯誤而終止程序運行。咱們將文件libmyhello.so複製到目錄/usr/lib中,再試試。若是不行,配置/etc/ld.so.conf; ldconfig試下。

# mv libmyhello.so /usr/lib
# ./hello   
Hello everyone!

成功了。這也進一步說明了動態庫在程序運行時是須要的。

當Linux靜態庫和Linux動態庫同名時, gcc命令將優先使用動態庫

相關文章
相關標籤/搜索