linux下c語言程式設計,動態鏈結和靜態鏈結的理解

2021-09-30 07:15:47 字數 2716 閱讀 5127

linux c語言開發 動態鏈結庫以及靜態鏈結庫程式設計簡單介紹 收藏

差不多可以認為,每個程式都鏈結到乙個或幾個庫上。任何乙個使用了c函式(諸如printf等)都須鏈結到c執行時庫。如果你的程式具有圖形介面(gui),它將被鏈結到視窗系統的庫。如果你的程式使用了資料庫,資料庫**商會提供給你一些簡化訪問資料庫的庫。

在這些情況中,你必須作出選擇:靜態(statically)還是動態(dynamically)地將程式鏈結到庫上。如果你選擇了靜態鏈結,程式體積可能會更大,程式也會比較難以公升級,但是可能相對而言比較易於部署。如果你選擇動態鏈結,則程式體積會比較小、易於公升級,但是部署的難度將會有所提高。本節中我們將介紹靜態和動態兩種鏈結方法,仔細比較它們的優劣,並提出一些在兩者之間選擇的簡單的規則。

>>>>靜態鏈結庫

靜態鏈結庫(static library)也被成為存檔檔案(archive),是乙個儲存了多個物件檔案(object frile)的單一檔案。編譯器在得到乙個存檔檔案後,會在這個存檔檔案中尋找需要的物件檔案,將其提取出來,然後與連線乙個單獨的物件檔案一樣將其連線到你的程式中。

你可以使用 ar 命令建立存檔檔案。傳統上,存檔檔案使用.a最為字尾名,以便與.o的物件檔案區分開。下面的命令可以將sub.o add.o合併成乙個libmyfun.a:

ar cr libmyfun.a sub.o add.o

當鏈結器在命令列引數中獲取到乙個存檔檔案時,它將在其中搜尋所有之前已經被引用而沒有被定義的符號(函式或變數)的定義。定義了這些符號的物件檔案將從存檔中被提取出來,鏈結到新程式執行檔案中。因為鏈結器會在讀取命令列引數的過程中一遇見存檔檔案就進行解析,通常將存檔檔案放在命令列引數的最後最有意義

舉例:/*sub.c*/

int sub(int a, int b)

return a - b;

/*add.c*/

int add(int a, int b)

return a + b;

下面將sub.c 與 add.c編譯為.o檔案:

gcc -c sub.c -o sub.o

gcc -c add.c -o add.o

將sub.o add.o合併為存檔檔案(靜態庫):

ar cr libmyfun.a add.o sub.o

編寫乙個測試程式來測試此靜態庫:

/*test.c*/

#include

int main(int argc, char* ar**)

printf("1 + 2 = %d/n", add(1, 2));

printf("1  - 2 = %d/n", sub(1, 2));

return 0;

下面為test.c的makefile:

src = test.c

objects = test.o

target = test

cc = gcc

cflag = -static

iflag = ./libmyfun.c

$(target):$(objects)

$(cc) $(cflag) -o $(target) $(objects) $(iflag)

.c.o:

$(cc) -c $<

clean:

rm -f *.o

rm *.bak

make 並執行 ./test得到期望的結果。

>>>>>>>>>>>.動態鏈結庫

共享庫(shared library,也被稱為共享物件shared object或動態鏈結庫dynamically linked library)在某種程度上與由一組物件檔案生成的打包檔案相當類似。不過,兩者之間的區別也是非常明顯的。最本質的區別在於,當乙個共享庫被鏈結到程式中的時候,程式本身並不會包含共享庫**現的**。程式僅包含乙個對共享庫的引用。當系統中有多個程式鏈結到同乙個共享庫的時候,它們都將引用這個共享庫而不是將**直接包含在自身程式中——正因為如此,我們說這個庫被所有這些程式「共享」。

第二個重要的區別在於,共享庫不僅僅是物件檔案的簡單組合。當使用的時候,鏈結器會從中尋找需要的部分進行鏈結,以匹配未定義的符號引用。而當生成共享庫的時候,所有物件檔案被合成為乙個單獨的物件檔案,從而使鏈結到這個庫的程式總能包含庫中的全部**,而不僅僅是所需要的部分。

要建立乙個共享庫,你必須在編譯那些用於生成共享庫的物件時為編譯器指定–fpic選項。

gcc –c –fpic test1.c

如果是多個檔案可以用如下方法實現動態庫的建立

編譯各個.o檔案

g++/gcc     -c   -fpic   -o   library1.o   library1.cpp      

g++/gcc     -c -fpic   -o   library2.o   library2.cpp      

g++/gcc     -c   -fpic   -o   libraryn.o   libraryn.cpp

連線成動態庫:           

g++/gcc   -g   -shared   -o libmydll.so lib1.0 lib2.0 .... libn.o

gcc -c  -fpic -o sub.o sub.c(或者: gcc -c -fpic sub.cpp -o sub.o)

gcc -c -fpic -o add.o add.c(或者: gcc -c -fpic add.cpp -o add.o)

連線成動態庫:

gcc -shared -o libmyfun.so add.o sub.o

Linux下C語言程式設計

include include include include define max 10pthread t thread 2 pthread mutex t mut int number 0 i void thread1 printf thread1 主函式在等我完成任務嗎?n pthread e...

Linux 下C語言程式設計

linux 下c語言程式設計 1.程式設計的概念和理解 1.1程式編譯的過程 在這一操作中,程式完成了複雜的過程。乙個程式的編譯,需要完成詞法分析 語法分析 中間 生成 優化 目標 生成。l 詞法分析 指的是對由字元組成的單詞進行處理,從左至右逐個字元地對源程式進行掃瞄,產生乙個個單詞符號。然後把字...

Linux下動態鏈結與靜態鏈結

一 首先我們來說一下庫的基礎概念 在windows平台和linux平台下都大量存在著庫。本質上來說庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。由於windows和linux的本質不同,因此二者庫的二進位制是不相容的。通俗的說就是把這些常用函式的目標檔案打包在一起,提供相應函式的介面...