靜態庫和動態庫的優缺點

2021-09-27 10:10:11 字數 3816 閱讀 1624

靜態庫和動態庫的優缺點

一、庫的型別

(一) 在windows中

.dll 動態庫

.lib 靜態庫

庫即為源**的二進位制檔案

(二) 在linux中

.so 動態庫

.a 靜態庫

(三) 靜態庫和動態庫的優缺點

我們通常把一些公用函式製作成函式庫,供其它程式使用。

函式庫分為靜態庫和動態庫兩種。

靜態庫在程式編譯時會被連線到目標**中,程式執行時將不再需要該靜態庫。

動態庫在程式編譯時並不會被連線到目標**中,而是在程式執行是才被載入,因此在程式執行時還需要動態庫存在

1.什麼是庫

在windows平台和linux平台下都大量存在著庫。

本質上來說庫是一種可執行**的二進位制形式,可以被作業系統載入記憶體執行。

由於windows和linux的本質不同,因此二者庫的二進位制是不相容的。

本文僅限於介紹linux下的庫

2.庫的種類

linux下的庫有兩種:靜態庫和共享庫(動態庫)。

二者的不同點在於**被載入的時刻不同。

靜態庫的**在編譯過程中已經被載入可執行程式,因此體積較大。

共享庫的**是在可執行程式執行時才載入記憶體的,在編譯過程中僅簡單的引用,因此**體積較小。

3.庫存在的意義

庫是別人寫好的現有的,成熟的,可以復用的**,你可以使用但要記得遵守許可協議。

現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的**都從零開始,因此庫的存在意義非同尋常。共享庫的好處是,不同的應用程式如果呼叫相同的庫,那麼在記憶體裡只需要有乙份該共享庫的例項。

4.庫檔案是如何產生的在linux下

靜態庫的字尾是.a,它的產生分兩步

step 1.由原始檔編譯生成一堆.o,每個.o裡都包含這個編譯單元的符號表

step 2.ar命令將很多.o轉換成.a,成文靜態庫

動態庫的字尾是.so,它由gcc加特定引數編譯產生。

例如:$ gcc -fpic -c *.c $ gcc -shared -wl,-soname, libfoo.so.1 -olibfoo.so.1.0 *.

5.庫檔案是如何命名的,有沒有什麼規範

在linux下,庫檔案一般放在/usr/lib和/lib下,

靜態庫的名字一般為lib***x.a,其中***x是該lib的名稱

動態庫的名字一般為lib***x.so.major.minor,***x是該lib的名稱,major是主版本號, minor是副版本號

6.如何知道乙個可執行程式依賴哪些庫

ldd命令可以檢視乙個可執行程式依賴的共享庫,

例如# ldd /bin/lnlibc.so.6

=> /lib/libc.so.6 (0×40021000)/lib/ld-linux.so.2

=> /lib/ld- linux.so.2 (0×40000000)

可以看到ln命令依賴於libc庫和ld-linux庫

7.可執行程式在執行的時候如何定位共享庫檔案

當系統載入可執行**時候,能夠知道其所依賴的庫的名字,但是還需要知道絕對路徑

此時就需要系統動態載入器(dynamiclinker/loader)

對於elf格式的可執行程式,是由ld-linux.so*來完成的

它先後搜尋elf檔案的 dt_rpath段—環境變數ld_library_path—/etc/ld.so.cache檔案列表—/lib/,/usr/lib目錄

找到庫檔案後將其載入記憶體

8.在新安裝乙個庫之後如何讓系統能夠找到他

如果安裝在/lib或者/usr/lib下,那麼ld預設能夠找到,無需其他操作。

如果安裝在其他目錄,需要將其新增到/etc/ld.so.cache檔案中,步驟如下

2.執行ldconfig,該命令會重建/etc/ld.so.cache檔案

linux中編譯靜態庫(.a)和動態庫(.so)的基本方法

(四) 靜態庫

在linux環境中, 使用ar命令建立靜態庫檔案.如下是命令的選項:

d -----從指定的靜態庫檔案中刪除檔案

m -----把檔案移動到指定的靜態庫檔案中

p -----把靜態庫檔案中指定的檔案輸出到標準輸出

q -----快速地把檔案追加到靜態庫檔案中

r -----把檔案插入到靜態庫檔案中

t -----顯示靜態庫檔案中檔案的列表

x -----從靜態庫檔案中提取檔案

還有多個修飾符修改以上基本選項,詳細請man ar 以下列出三個:

a -----把新的目標檔案(*.o)新增到靜態庫檔案中現有檔案之後

b-----***************************************之前

v -----使用詳細模式

ar 命令的命令列格式如下:

ar[-][abcfilnopssuvv] [membername] [count] archive files...
引數archive定義庫的名稱, files是庫檔案中包含的目標檔案的清單, 用空格分隔每個檔案.

比如建立乙個靜態庫檔案的命令如下:

ar r libapue.a error.oerrorlog.o lockreg.o
這樣就了libapue.a靜態庫檔案, 可以用 t 選項顯示包含在庫中的檔案

建立庫檔案之後,可以建立這個靜態庫檔案的索引來幫助提高和庫連線的其他程式的編譯速度:

使用ranlib程式建立庫的索引,索引存放在庫檔案內部.

ranlib libapue.a
用nm程式顯示存檔檔案的索引,它可以顯示目標檔案的符號

nm libapue.a | more

如果是顯示目標檔案的符號:

nm error.o | more

如何使用呢?如下所示:

gcc -o test test.c libapue.a

這樣就可以在test.c中呼叫在libapue.a中的函式了.

(五) 動態庫

1.建立共享庫

gcc -shared -o libapue.soerror.o errorlog.o

這樣就建立了共享庫!

2.編譯共享庫

假設共享庫位於當前目錄(即跟程式檔案相同的目錄中)

gcc -o test -l. -lapue test.c

這樣就編譯出了不包含函式**可執行檔案了,但是但你執行時會發現linux動態載入器找不到libapue.so檔案.

可以用ldd 命令檢視可執行檔案依賴什麼共享庫:

ldd test

如何才能讓動態載入器發現庫檔案呢?有兩種方法可以解決:

1.環境變數

exportld_library_path="$ld_library_path:."

2.修改/etc/ld.so.conf檔案.

一般應用程式的庫檔案不與系統庫檔案放在同乙個目錄下,一般把應用程式的共享庫檔案放在/usr/local/lib下,新建乙個屬於自己的目錄apue,然後把剛才libapue.so複製過去就行了

同時在/etc/ld.so.conf中新增一行:

/usr/local/lib/apue

以後在編譯程式時加上編譯選項:

-l /usr/local/lib/apue -lapue

引數的配置通過mangcc可以看到

-llibrary

連線名為 library 的 庫檔案.

聯結器 在 標準搜尋目錄 中 尋找 這個 庫檔案, 庫檔案 的 真正 名 字

Linux 靜態庫和動態庫的優缺點

靜態庫在程式編譯時,直接將庫中的 鏈結到可執行程式中。缺點 加入多個程式共同使用同乙個靜態庫,相當於把多段相同的 儲存在不同的可執行程式中,在空間上有一定浪費。1.使可執行程式執行速度快 2.浪費一定的空間 可執行程式只儲存對應的函式引用表,只有程式執行時,再鏈結對應的庫。1.節省空間 2.執行速度...

動態庫與靜態庫優缺點比較

從本質上來說是一種可執行 的二進位制格式,可以被載入記憶體中執行。庫分靜態庫和動態庫兩種 1.靜態函式庫 這類庫的名字一般是lib a 利用靜態函式庫編譯成的檔案比較大,因為整個 函式庫的所有資料都會被整合進目標 中,他的優點就顯而易見了,即編譯後的執行程式不需要外部的函式庫支援,因為所有使用的函式...

Linux 動態庫 靜態庫的生成 使用和優缺點分析

一 介紹 在軟體程式設計中,通常會把功能或介面函式封裝成庫的形式,供給其它模組或第三方使用。在linux系統中存在動態庫和靜態庫兩種形式。靜態庫 以lib a形式命名,編譯程式時,會將靜態庫資料編譯進可執行程式中。動態庫 以lib so形式命名,編譯程式時,不會被編譯進可執行程式中,而在程式執行時,...