關於Linux靜態庫和動態庫的分析
關於Linux靜態庫和動態庫的分析
關於Linux靜態庫和動態庫的分析 1.什麽是庫
函數庫分為靜態庫和動態庫兩種。 靜態庫在程序編譯時會被連接到目標代碼中,程序執行時將不再須要該靜態庫。動態庫在程序編譯時並不會被連接到目標代碼中。而是在程序執行是才被加載,因此在程序執行時還須要動態庫存在。 本文主要通過舉例來說明在Linux 中怎樣創建靜態庫和動態庫,以及使用它們。在創建函數庫前,我們先來準備舉例用的源程序,並將函數庫的源程序編譯成.o文件。 第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! # 成功了。這也進一步說明了動態庫在程序執行時是須要的。
|
關於Linux靜態庫和動態庫的分析