靜態庫與動態庫

2021-07-28 18:40:45 字數 2355 閱讀 8516

編譯系統在編譯的過程中,將所有相關的目標模組打包成乙個單獨的檔案,稱為靜態庫(static library),它可以用做鏈結器的輸入。當鏈結器構造乙個輸出的可執行檔案時,它只拷貝靜態庫里被應用程式引用的目標模組。

在unix系統中,靜態庫以一種稱為存檔(archive)的特殊檔案格式存放在磁碟中。存檔檔案是一組連線起來的可重定位目標檔案的集合,有乙個頭部用來描述每個成員目標檔案的大小和位置。存檔檔名由字尾.a標識。為了使我們對庫的討論更加形象具體,假設我們想在乙個叫做libvector.a的靜態庫中提供如下的向量例程:

/* file name: addvec.c */

void addvec(int *x, int *y,

int *z, int n)

}

/* file name: multvec.c */

void multvec(int *x, int *y,

int *z, int n)

}

為了建立該庫,我們使用ar工具:

unix> gcc -c addvec.c multvec.c

unix> ar rcs libvector.a addvec.o multvec.o

為了使用這個庫,我們可以編寫乙個應用(main.c),它呼叫addvec庫例程。(包含標頭檔案vector.h定義了libvector.a中例程的函式原型)。

/* file name: main.c */

#include

#include "vector.h"

int x[2] = ;

int y[2] = ;

int z[2];

int main()

/* file name: vector.h */

void addvec(int *x, int *y,

int *z, int n);

void multvec(int *x, int *y,

int *z, int n);

unix> gcc -o2

-c main.c

unix> gcc -static

-o p2 main.o ./libvector.a

下圖概括了鏈結器的行為。

靜態庫解決了許多關於如何讓大量相關函式對應用程式可用的問題。然而,靜態庫仍然有一些明顯的缺點。靜態庫和所有的軟體一樣,需要定期維護和更新。另乙個問題是幾乎每個c程式都使用標準i/o函式,如printfscanf。在執行時,這些函式的**會被複製到每個執行程序的文字段中。在乙個執行50-100個程序的典型系統上,這將是對稀缺的儲存器系統資源的極大浪費。

共享庫(shared library)是致力於解決靜態庫缺陷的乙個現代創新產物。共享庫是乙個目標模組,在執行時,可以載入到任意的儲存器位址,並和乙個在儲存器中的程式鏈結起來。這個過程稱為動態鏈結(dynamic linking),是由乙個叫做動態鏈結器(dynamic linker)的程式來執行的。

共享庫也稱為共享目標(shared object),在unix系統中通常用.so字尾來表示。微軟的作業系統大量地利用了共享庫,它們稱為dll(動態鏈結庫)。

共享庫是以兩種不同的方式來「共享」的。首先,在任何給定的檔案系統中,對於乙個庫只有乙個.so檔案。所有引用該庫的可執行目標檔案共享這個.so檔案中的**和資料,而不是像靜態庫的內容那樣被拷貝到引用它們的可執行的檔案中。其次,在儲存器中,乙個共享庫的.text節的乙個副本可以被不同的正在執行的程序共享。

unix> gcc -shared -fpic -o libvector.so addvec.c multvec.c

unix> gcc -o p2 main.c ./libvector.so

鏈結過程如下圖:

靜態庫與動態庫

linux下靜態庫 a 的例子 mylib.h 位於include資料夾下 ifndef mylib h define mylib h int add int a,int b endif mylib.cpp 位於lib資料夾中 include mylib.h int add int a,int b ...

靜態庫與動態庫

庫本質上是一種可執行的二進位制 可以被作業系統載入 linux和windows的庫是不相容的 庫可以分為靜態塊和動態庫,二者的不同點在於 被載入的時刻不同。靜態庫 在程式編譯時會被連線到目標 中,程式執行時不再需要改靜態庫,體積較大,一般應用與移植過程中在宿主機上編譯的 靜態庫檔名的命名規範是以li...

靜態庫與動態庫

1.靜態庫 工程在呼叫靜態庫時,複製靜態庫,源 加長,不節省程式空間。字尾名.a 優點 程式設計後不需要再依賴庫 以空間換時間 建立靜態庫 gcc c 原始檔.c ar rcs rcu 靜態庫名 目標檔案1 目標檔案2 rc 靜態庫不存在,就建立該庫檔案 s 更新靜態庫 使用 gcc o file ...