當前位置:首頁 » 操作系統 » linux下的靜態庫

linux下的靜態庫

發布時間: 2022-08-31 23:25:25

linux動態庫和靜態庫的區別

靜態庫:這類庫的名字一般是libxxx.a,xxx為庫的名字。利用靜態函數庫編譯成的文件比較大,因為整個函數庫的所有數據都會被整合進目標代碼中,他的優點就顯而易見了,即編譯後的執行程序不需要外部的函數庫支持,因為所有使用的函數都已經被編譯進去了。當然這也會成為他的缺點,因為如果靜態函數庫改變了,那麼你的程序必須重新編譯。
動態庫:這類庫的名字一般是libxxx.M.N.so,同樣的xxx為庫的名字,M是庫的主版本號,N是庫的副版本號。當然也可以不要版本號,但名字必須有。相對於靜態函數庫,動態函數庫在編譯的時候並沒有被編譯進目標代碼中,你的程序執行到相關函數時才調用該函數庫里的相應函數,因此動態函數庫所產生的可執行文件比較小。由於函數庫沒有被整合進你的程序,而是程序運行時動態的申請並調用,所以程序的運行環境中必須提供相應的庫。動態函數庫的改變並不影響你的程序,所以動態函數庫的升級比較方便。linux系統有幾個重要的目錄存放相應的函數庫,如/lib
/usr/lib。
當要使用靜態的程序庫時,連接器會找出程序所需的函數,然後將它們拷貝到執行文件,由於這種拷貝是完整的,所以一旦連接成功,靜態程序庫也就不再需要了。然而,對動態庫而言,就不是這樣。動態庫會在執行程序內留下一個標記指明當程序執行時,首先必須載入這個庫。由於動態庫節省空間,linux下進行連接的預設操作是首先連接動態庫,也就是說,如果同時存在靜態和動態庫,不特別指定的話,將與動態庫相連接。

❷ linux下的靜態庫與動態庫的區別和使用

一、引言

我們通常把一些公用函數製作成函數庫,供其它程序使用。
函數庫分為靜態庫和動態庫兩種。

通常情況下,對函數庫的鏈接是放在編譯時期(compile time)完成的。所有相關的對象文件(object file)與牽涉到的函數庫(library)被鏈接合成一個可執行文件(executable file)。程序在運行時,與函數庫再無瓜葛,因為所有需要的函數已拷貝到相應目錄下下。所以這些函數庫被成為靜態庫(static libaray),通常文件名為「libxxx.a」的形式。

其實,我們也可以把對一些庫函數的鏈接載入推遲到程序運行的時期(runtime)。這就是動態鏈接庫(dynamic link library)技術。

二、兩者區別:
a,靜態庫的使用需要:
1 包含一個對應的頭文件告知編譯器lib文件裡面的具體內容
2 設置lib文件允許編譯器去查找已經編譯好的二進制代碼

b,動態庫的使用:
程序運行時需要載入動態庫,對動態庫有依賴性,需要手動加入動態庫

c,依賴性:
靜態鏈接表示靜態性,在編譯鏈接之後, lib庫中需要的資源已經在可執行程序中了, 也就是靜態存在,沒有依賴性了
動態,就是實時性,在運行的時候載入需要的資源,那麼必須在運行的時候提供 需要的 動態庫,有依賴性, 運行時候沒有找到庫就不能運行了

d,區別:
簡單講,靜態庫就是直接將需要的代碼連接進可執行程序;動態庫就是在需要調用其中的函數時,根據函數映射表找到該函數然後調入堆棧執行。
做成靜態庫可執行文件本身比較大,但不必附帶動態庫
做成動態庫可執行文件本身比較小,但需要附帶動態庫
鏈接靜態庫,編譯的可執行文件比較大,當然可以用strip命令精簡一下(如:strip libtest.a),但還是要比鏈接動態庫的可執行文件大。程序運行時間速度稍微快一點。
靜態庫是程序運行的時候已經調入內存,不管有沒有調用,都會在內存里頭。靜態庫在程序編譯時會被連接到目標代碼中,程序運行時將不再需要該靜態庫。
其在編譯程序時若鏈接,程序運行時會在系統指定的路徑下搜索,然後導入內存,程序一般執行時間稍微長一點,但編譯的可執行文件比較小;動態庫是程序運行的時候需要調用的時候才裝入內存,不需要的時候是不會裝入內存的。
動態庫在程序編譯時並不會被連接到目標代碼中,而是在程序運行是才被載入,因此在程序運行時還需要動態庫存在。

三、動態鏈接庫的特點與優勢

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

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

什麼概念呢?就是說,某個程序的在運行中要調用某個動態鏈接庫函數的時候,操作系統首先會查看所有正在運行的程序,看在內存里是否已有此庫函數的拷貝了。如果有,則讓其共享那一個拷貝;只有沒有才鏈接載入。這樣的模式雖然會帶來一些「動態鏈接」額外的開銷,卻大大的節省了系統的內存資源。C的標准庫就是動態鏈接庫,也就是說系統中所有運行的程序共享著同一個C標准庫的代碼段。

2. 將一些程序升級變得簡單。用戶只需要升級動態鏈接庫,而無需重新編譯鏈接其他原有的代碼就可以完成整個程序的升級。Windows 就是一個很好的例子。

3. 甚至可以真正坐到鏈接載入完全由程序員在程序代碼中控制。

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

靜態庫:在編譯的時候載入生成目標文件,在運行時不用載入庫,在運行時對庫沒有依賴性。
動態庫:在目標文件運行時載入,手動載入,且對庫有依賴性。

具體在開發中用到哪種庫,我覺得還是根據實際的內存大小,ROM大小,運行的速度等綜合考慮。

❸ linux下怎麼 調用 和生成 靜態庫

Linux庫有動態與靜態兩種,動態通常用.so為後綴,靜態用.a為後綴。例如:libhello.so libhello.a 為了在同一系統中使用不同版本的庫,可以在庫文件名後加上版本號為後綴,例如: libhello.so.1.0,由於程序連接默認以.so為文件後綴名。所以為了使用這些庫,通常使用建立符號連接的方式。 ln -s libhello.so.1.0 libhello.so.1 ln -s libhello.so.1 libhello.so 動態庫和靜態庫的區別: 當要使用靜態的程序庫時,連接器會找出程序所需的函數,然後將它們拷貝到執行文件,由於這種拷貝是完整的,所以一旦連接成功,靜態程序庫也就不再需要了。然而,對動態庫而言,就不是這樣。動態庫會在執行程序內留下一個標記『指明當程序執行時,首先必須載入這個庫。由於動態庫節省空間,linux下進行連接的預設操作是首先連接動態庫,也就是說,如果同時存在靜態和動態庫,不特別指定的話,將與動態庫相連接。 兩種庫的編譯產生方法: 第一步要把源代碼編繹成目標代碼。以下面的代碼hello.c為例,生成hello庫: /* hello.c */ #include void sayhello() { printf("hello,world\n"); } 用gcc編繹該文件,在編繹時可以使用任何全法的編繹參數,例如-g加入調試代碼等

❹ linux a 靜態庫 怎麼設置

Linux的靜態庫文件並不需要設置啊,編譯鏈接.a靜態庫文件時只需要加上.a文件的完整路徑就可以了,比如:
gcc
-o
hello
hello.c
/usr/lib/libm.a
只有編譯鏈接動態庫才需要用-L選項來設置動態庫的搜索路徑,比如這個命令:
gcc
-o
hello
hello.c
-L/usr/openssl/lib
-lcrypto

❺ 如何生成linux下的動態庫和靜態庫

靜態庫 靜態庫的後綴是.a,它的產生分兩步 Step 1.由源文件編譯生成一堆.o,每個.o里都包含這個編譯單元的符號表Step 2.ar命令將很多.o轉換成.a,成為靜態庫動態庫的後綴是.so,它由gcc加特定參數編譯產生。具體方法參見後文實例。123123 在 GNU...

❻ linux下的靜態庫創建與查看,及如何查看某個可執行依賴於哪些動態庫

創建靜態庫:
ar -rcs test.a *.o
查看靜態庫:
ar -tv test.a
解壓靜態庫:
ar -x test.a

查看程序依賴的動態庫:
readelf -a xxx|grep library
如:可以看到,下面的交叉程序hello執行依賴於如下兩個動態庫。
rebi@ubuntu:~/test$ arm-none-linux-gnueabi-readelf -a hello|grep "library"
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
rebi@ubuntu:~/test$

或者:readelf -l hello 即可。

nm xxx 查看符號
其中,T表示代碼段,U表示在其它地方定義,所以需要確保必須在某個.o或庫里被定義過。

❼ linux靜態庫怎麼編譯

linux庫有動態與靜態兩種,動態通常用.so為後綴,靜態用.a為後綴。例如:libhello.so
libhello.a
為了在同一系統中使用不同版本的庫,可以在庫文件名後加上版本號為後綴,例如:
libhello.so.1.0,由於程序連接默認以.so為文件後綴名。所以為了使用這些庫,通常使用建立符號連接的方式。
ln
-s
libhello.so.1.0
libhello.so.1
ln
-s
libhello.so.1
libhello.so
動態庫和靜態庫的區別:
當要使用靜態的程序庫時,連接器會找出程序所需的函數,然後將它們拷貝到執行文件,由於這種拷貝是完整的,所以一旦連接成功,靜態程序庫也就不再需要了。然而,對動態庫而言,就不是這樣。動態庫會在執行程序內留下一個標記『指明當程序執行時,首先必須載入這個庫。由於動態庫節省空間,linux下進行連接的預設操作是首先連接動態庫,也就是說,如果同時存在靜態和動態庫,不特別指定的話,將與動態庫相連接。
兩種庫的編譯產生方法:
第一步要把源代碼編繹成目標代碼。以下面的代碼hello.c為例,生成hello庫:
/*
hello.c
*/
#include
void
sayhello()
{
printf("hello,world\n");
}
用gcc編繹該文件,在編繹時可以使用任何全法的編繹參數,例如-g加入調試代碼等:
gcc
-c
hello.c
-o
hello.o
1.連接成靜態庫
連接成靜態庫使用ar命令,其實ar是archive的意思
$ar
cqs
libhello.a
hello.o
2.連接成動態庫
生成動態庫用gcc來完成,由於可能存在多個版本,因此通常指定版本號:
$gcc
-shared
-wl,-soname,libhello.so.1
-o
libhello.so.1.0
hello.o
另外再建立兩個符號連接:
$ln
-s
libhello.so.1.0
libhello.so.1
$ln
-s
libhello.so.1
libhello.so
這樣一個libhello的動態連接庫就生成了。最重要的是傳gcc
-shared
參數使其生成是動態庫而不是普通執行程序。
-wl
表示後面的參數也就是-soname,libhello.so.1直接傳給連接器ld進行處理。實際上,每一個庫都有一個soname,當連接器發現它正在查找的程序庫中有這樣一個名稱,連接器便會將soname嵌入連結中的二進制文件內,而不是它正在運行的實際文件名,在程序執行期間,程序會查找擁有
soname名字的文件,%b

❽ Linux下的靜態庫和動態庫

linux下的靜態庫和動態庫1.製作自己的動態庫和靜態庫linux下動態庫以.so結尾,靜態庫以.a結尾,它們都以lib開頭,比如一個庫名為net,那麼它的全名應該是libnet.so或者libnet.a。我們有兩個文件,hello.c和test.c,下面是兩個文件的內容//hello.c
www.shiwu.com
#include
<stdio.h>void
my_lib_func(){printf(Library
routine
called/r/n);}//test.c#include
<stdio.h>
www.shiwu.com
int
main(){my_lib_func();return
1;}test.c調用了hello.c的方法,我們把hello.c封裝成庫文件。無論是靜態庫還是動態庫,都是由.o文件組成,我們先把gcc
-c
hello.c生成.o文件製作靜態庫ar
crv
libmyhello.a
hello.o,ar是生成靜態庫的命令,libmyhello.a是我的靜態庫名。下一步就是在我的程序中使用靜態庫
可以看到已經有了Library
routine
called的結果,說明調用成功了。下面我們刪除libmyhello.a,看看程序是否還是運行正常
我們發現程序依然運行正常,說明靜態庫已經連接進入我們的程序中製作動態庫
www.shiwu.com
我們看見動態庫libmyhello.so已經生成,下面繼續使用
找不到庫文件,這個時候我們把so文件拷貝到/usr/lib下面
運行成功2.動態庫和靜態庫同時存在的調用規則我們可以發現,不論是動態庫還是靜態庫,程序編譯連接的時候都是加的參數-l,那麼當他們同時存在的時候,程序會選擇動態庫還是靜態庫呢。我們做個嘗試。
我們同時存在libmyhello.a和libmyhello.so,我們發現運行的時候,出現找不到動態庫的錯誤,由此,我們可以得出結論,同時存在動態庫和靜態庫的時候,gcc會優先選擇動態庫作者
梨樹陽光

❾ linux靜態庫和共享庫的區別

linux下的庫有兩種:靜態庫和共享庫(動態庫)。二者的不同點在於代碼被載入的時刻不同。
靜態庫在程序編譯時會被連接到目標代碼中,目標程序運行時將不再需要該動態庫,移植方便,體積較大,但是浪費空間和資源,因為所有相關的對象文件與牽涉到的庫被鏈接合成一個可執行文件。
動態庫在程序編譯時並不會被連接到目標代碼中,而是在程序運行時才被載入,因此體積較小,可以實現進程間的資源共享,甚至可以真正做到鏈接載入完全由程序員在程序代碼中控制,另外將一些程序的升級變得簡單,但是在程序運行時需要動態庫存在。

❿ Linux中如何創建靜態庫和動態庫

靜態庫在程序編譯時會被連接到目標代碼中,程序運行時將不再需要該靜態庫。 動態庫在程序編譯時並不會被連接到目標代碼中,而是在程序運行是才被載入,因此在程序運行時還需要動態庫存在。 程序1: hello.h #ifndef HELLO_H #define HELLO_H void hello(const char *name); #endif //HELLO_H 程序2: hello.c #include void hello(const char *name) { printf("Hello %s!\n", name); } 程序3: main.c #include "hello.h" int main() { hello("everyone"); return 0; } 無論動態庫還是靜態庫都需要用到.o文件來生成,先編譯生成.o文件。 # gcc -c hello.c 1:創建靜態庫 靜態庫文件名的命名規范是以lib為前綴,緊接著跟靜態庫名,擴展名為.a。例如:我們將創建的靜態庫名為myhello,則靜態庫文件名就是libmyhello.a。 # ar cr libmyhello.a hello.o 使用靜態庫:只需要在你的源程序中加入包含你所需要使用到的函數的聲明(即包含頭文件),然後在gcc生成目標文件時候指明靜態庫就OK了(除非你包含的頭文件在/usr/include,庫文件在標准庫/usr/lib,/lib下,否則你得顯示指明他們的路徑) # gcc -o hello main.c -L. -lmyhello # ./hello Hello everyone! 刪除靜態庫文件運行./hello,程序正常運行,說明靜態庫公用函數已經鏈接到目標文件。 2: 利用.o文件創建動態庫 動態庫文件擴展名為.so。 # gcc -shared -fPCI -o libmyhello.so hello.o 動態庫的使用與靜態庫使用方式一樣 # gcc -o hello main.c -L. -lmyhello # ./hello ./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory 哦!出錯了。快看看錯誤提示,原來是找不到動態庫文件libmyhello.so。程序在運行時,會在/usr/lib和/lib等目錄中查找需要的動態庫文件。若找到,則載入動態庫,否則將提示類似上述錯誤而終止程序運行。

熱點內容
如何下載奧特曼高級化3安卓版 發布:2025-05-14 07:47:31 瀏覽:346
qml文件修改後編譯未生效 發布:2025-05-14 07:31:00 瀏覽:331
內到內演算法 發布:2025-05-14 07:29:11 瀏覽:34
文件夾名字不顯示 發布:2025-05-14 07:27:47 瀏覽:775
oracle的資料庫驅動jar 發布:2025-05-14 07:23:20 瀏覽:556
我的世界電腦版伺服器手機版能進嗎 發布:2025-05-14 07:22:01 瀏覽:679
達內培訓php多少錢 發布:2025-05-14 07:19:10 瀏覽:27
python位元組轉字元串 發布:2025-05-14 07:06:35 瀏覽:422
subplotpython 發布:2025-05-14 06:53:51 瀏覽:662
豎屏大屏導航工廠密碼一般是多少 發布:2025-05-14 06:49:29 瀏覽:807