關於Linux靜態庫和動態庫的分析
1.什麼是庫
第1步:編輯得到舉例的程序--hello.h、hello.c和main.c; hello.h(見程序1)爲該函數庫的頭文件。 hello.c(見程序2)是函數庫的源程序,其中包含公用函數hello,該函數將在屏幕上輸出"Hello XXX!"。 main.c(見程序3)爲測試庫文件的主程序,在主程序中調用了公用函數hello。
程序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); } #include "hello.h"
int main() { hello("everyone"); return 0; }
第2步:將hello.c編譯成.o文件; 無論靜態庫,還是動態庫,都是由.o文件創建的。因此,我們必須將源程序hello.c通過gcc先編譯成.o文件。 在系統提示符下鍵入以下命令得到hello.o文件。 # gcc -c hello.c 我們運行ls命令看看是否生存了hello.o文件。 # ls hello.c hello.h hello.o main.c 在ls命令結果中,我們看到了hello.o文件,本步操作完成。 下面我們先來看看如何創建靜態庫,以及使用它。
第3步:由.o文件創建靜態庫; 靜態庫文件名的命名規範是以lib爲前綴,緊接着跟靜態庫名,擴展名爲.a。例如:我們將創建的靜態庫名爲myhello,則靜態庫文件名就是libmyhello.a。在創建和使用靜態庫時,需要注意這點。創建靜態庫用ar命令。 在系統提示符下鍵入以下命令將創建靜態庫文件libmyhello.a。 # ar cr libmyhello.a hello.o 我們同樣運行ls命令查看結果:# ls ls命令結果中有libmyhello.a。 hello.c hello.h hello.o libmyhello.a main.c 第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 -shared -fPIC -o libmyhello.so hello.o 我們照樣使用ls命令看看動態庫文件是否生成。# ls hello.c hello.h hello.o libmyhello.so main.c
第6步:在程序中使用動態庫; 在程序中使用動態庫和使用靜態庫完全一樣,也是在使用到這些公用函數的源程序中包含這些公用函數的原型聲明,然後在用gcc命令生成目標文件時指明動態庫名進行編譯。我們先運行gcc命令生成目標文件,再運行它看看結果。 # gcc -o hello main.c -L. –lmyhello $gcc–o app main.c /home/test/program/ibmyLib.so $gcc -o app2 main.c $PWD/libmyhelloso.so # ./hello ./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory # 哦!出錯了。快看看錯誤提示,原來是找不到動態庫文件libmyhello.so。程序在運行時,會在/usr/lib和/lib等目錄中查找需要的動態庫文件。若找到,則載入動態庫,否則將提示類似上述錯誤而終止程序運行。我們將文件libmyhello.so複製到目錄/usr/lib中,再試試。 # mv libmyhello.so /usr/lib # ./hello ./hello: error while loading shared libraries: /usr/lib/libhello.so: cannot restore segment prot after reloc: Permission denied # chcon -t texrel_shlib_t /usr/lib/libhello.so # ./hello Hello everyone! # 成功了。這也進一步說明了動態庫在程序運行時是需要的。 |