Linux 下 C C 靜態庫 動態庫的區別

2021-08-08 03:25:46 字數 3366 閱讀 4050

linux

linux

下的庫必須以

lib開頭,用於系統識別

靜態庫 字尾 .a  每次被呼叫都生成乙個副本

共享庫(動態庫) 字尾.so  只有乙個副本

windows

靜態庫 字尾 .lib

動態庫 字尾.dll

靜態庫的生成和使用

通常情況下,對函式庫的鏈結是放在編譯時期(compile time)完成的。所有相關的物件檔案(object file)與牽涉到的函式庫(library)被鏈結合成乙個可執行檔案(executable file)。程式在執行時,

與函式庫再無瓜葛,因為所有需要的函式已拷貝到自己門下

。所以這些函式庫被成為靜態庫(static libaray),通常檔名為「lib***.a」的形式。

靜態庫必要的目標**的是在對程式編譯的時候被加入到程式中

,而執行時不再需要

.a的庫了

生成靜態庫:

gcc -c try1.c  

gcc -c try2.c

ar cqs libtry.a try1.o try2.o(或 ar r libtry.a try1.o try2.o)

使用:

gcc -c main.c -o main.o  

gcc main.o -o name -l. -ltry (-l後面的名字就是我們上面生成的try庫)

動態庫的生成和使用

動態鏈結庫的特點與優勢

首先讓我們來看一下,把庫函式推遲到程式執行時期載入的好處:

1. 可以實現程序之間的資源共享。

什麼概念呢?就是說,某個程式的在執行中要呼叫某個動態鏈結庫函式的時候,作業系統首先會檢視所有正在執行的程式,看在記憶體裡是否已有此庫函式的拷貝了。如果有,則讓其共享那乙個拷貝;只有沒有才鏈結載入。這樣的模式雖然會帶來一些「動態鏈結」額外的開銷,卻大大的節省了系統的記憶體資源。c的標準庫就是動態鏈結庫,也就是說系統中所有執行的程式共享著同乙個c標準庫的**段。

2. 將一些程式公升級變得簡單。使用者只需要公升級動態鏈結庫,而無需重新編譯鏈結其他原有的**就可以完成整個程式的公升級。windows 就是乙個很好的例子。

3. 甚至可以真正坐到鏈結載入完全由程式設計師在程式**中控制。

程式設計師在編寫程式的時候,可以明確的指明什麼時候或者什麼情況下,鏈結載入哪個動態鏈結庫函式。你可以有乙個相當大的軟體,但每次執行的時候,由於不同的操作需求,只有一小部分程式被載入記憶體。所有的函式本著「有需求才調入」的原則,於是大大節省了系統資源。比如現在的軟體通常都能開啟若干種不同型別的檔案,這些讀寫操作通常都用動態鏈結庫來實現。在一次執行當中,一般只有一種型別的檔案將會被開啟。所以直到程式知道檔案的型別以後再載入相應的讀寫函式,而不是一開始就將所有的讀寫函式都載入,然後才發覺在整個程式中根本沒有用到它們。

把乙個源**編譯成

.so:

gcc -shared -o libtry.so try.c  

1.顯式呼叫

不推薦2.隱式呼叫

所謂隱式呼叫,就是呼叫的時候直接使用動態庫中的函式,並不區別對待。

但是在隱式呼叫的時候必須要讓程式能找到你所呼叫的函式的所屬動態庫。

我們先來建立乙個感性認識: #

more /etc/ld.so.conf

你會看到以下內容:

/usr/kerberos/lib    

/usr/x11r6/lib    

/usr/lib/sane    

/usr/lib/qt-3.1/lib    

/usr/lib/mysql    

/usr/lib/qt2/lib    

/usr/local/lib    

/usr/local/berkeleydb.4.3/lib

ld.so.conf

是系統對動態鏈結庫進行查詢的路徑配置檔案,也就是說該檔案是系統鏈結工具

/usr/bin/ld a.

將自己的動態鏈結庫檔案拷到以上路徑的目錄下

# cp libwx.so.1 /usr/local/lib b.

將自己動態鏈結庫檔案的路徑加入到該檔案中

# vi /etc/ld.so.conf

,然後加入自己的路徑(或

pwd >>/etc/ld.so.conf) (

千萬不要將

>>

寫成》,前者是新增,後者是覆蓋)

c.把當前路徑加入環境變數

ld_library_path

,其實就是

/usr/bin/ld

的環境變數

# export ld_library_path=.:$ld_library_path

編譯的時候:

# gcc -o try main.c libtry.so.1    

如果沒有讓

/usr/bin/ld

# gcc -o try main.c /root/libtry.so.1 (

或:# gcc -l/root/wx -o qqq main.c libmy.so.1) -l

指定動態鏈結庫所在的目錄,有時候用

gcc還會碰到-i,

-l,他們分別指定標頭檔案的目錄和所鏈結的動態鏈結庫

# ldd try   

用來檢視可執行檔案

qqq的動態鏈結庫的依賴關係 如

libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x00867000)

libsdl-1.2.so.0 => /usr/lib/libsdl-1.2.so.0 (0x0638a000)

libc.so.6 => /lib/tls/libc.so.6 (0x0046d000)

libm.so.6 => /lib/tls/libm.so.6 (0x00598000)

libdl.so.2 => /lib/libdl.so.2 (0x005bd000)

libasound.so.2 => /lib/libasound.so.2 (0x062e1000)

libx11.so.6 => /usr/x11r6/lib/libx11.so.6 (0x005d5000)

libxext.so.6 => /usr/x11r6/lib/libxext.so.6 (0x0069e000)

libpthread.so.0 => /lib/tls/libpthread.so.0 (0x006ae000)

/lib/ld-linux.so.2 (0x00450000)

c c 靜態庫動態庫( )

預處理 gcc g e test.cpp 編譯主要動作 將預處理後的檔案轉換為彙編檔案,裡面為彙編指令 gcc g s test.cpp 彙編主要動作 將彙編檔案轉換為目標檔案,生成.o檔案,即目標檔案 gcc g c test.cpp 主要動作 將目標檔案和庫檔案集成為可執行檔案 鏈結主要動作 將...

linux 下靜態庫和動態庫

我們通常把一些公用函式製作成函式庫,供其它程式使用。函式庫分為靜態庫和動態庫兩種。靜態庫在程式編譯時會被連線到目標 中,程式執行時將不再需要該 靜態庫。動態庫在程式編譯時並不會被連線到目標 中,而是在程式執行是才被載入,因此在程式執行時還需要動態庫存在。本文主要通過舉例來說明在 linux中如何建立...

Linux下的動態庫和靜態庫

靜態庫 程式編譯時載入,可執行程式體積大。一般命名為lib x.a。動態庫 程式執行時載入,可執行程式體積小。一般命名為lib x.so.1.3。x一般指庫名,如libxml2 tinyxml等 動態庫一般預設安裝在 lib 或者 usr lib 或者 usr local lib下。如果安裝的庫不在...