Linux下動態鏈結與靜態鏈結

2021-09-28 22:36:01 字數 2457 閱讀 4621

一、首先我們來說一下庫的基礎概念:

在windows平台和linux平台下都大量存在著庫。本質上來說庫是一種可執行**的二進位制形式,可以被作業系統載入記憶體執行。由於windows和linux的本質不同,因此二者庫的二進位制是不相容的。通俗的說就是把這些常用函式的目標檔案打包在一起,提供相應函式的介面,便於程式設計師使用。在使用函式時,只需要包對應的標頭檔案即可。按照庫的使用方式又可分為動態庫和靜態庫,在不同平台下對應字尾也有所不同。

作為一名程式設計師,對於編譯鏈結的過程要了然於胸。

首先大概介紹一下,編譯分為3步,首先對原始檔進行預處理,這個過程主要是處理一些#號定義的命令或語句(如巨集、#include、預編譯指令#ifdef等),生成*.i檔案;

然後進行編譯,這個過程主要是進行詞法分析、語法分析和語義分析等,生成*.s的彙編檔案;

最後進行彙編,這個過程比較簡單,就是將對應的彙編指令翻譯成機器指令,生成可重定位的二進位制目標檔案。

以上就是編譯的過程,下面主要介紹兩種鏈結方式–靜態鏈結和動態鏈結。

靜態鏈結和動態鏈結兩者最大的區別就在於鏈結的時機不一樣,靜態鏈結是在形成可執行程式前,而動態鏈結的進行則是在程式執行時,下面來詳細介紹這兩種鏈結方式。

windows下:.dll 字尾為動態庫,.lib 字尾為靜態庫;

linux下:.so字尾為動態庫,.a字尾為靜態庫。

比較靜態庫

動態庫概念

靜態鏈結庫就是乙個多個彙編檔案(obj檔案)的集合,在linux中通常命名為lib***.a。對於靜態鏈結庫函式的連線是在編譯階段,直接將obj檔案的乙份拷貝**連線到目標檔案。

動態鏈結庫也是乙個或多個彙編檔案的集合,在linux中通常命名為lib***.so。對於動態鏈結庫函式的鏈結是在執行階段,各個目標程式之間共享同乙份庫檔案。在編譯階段僅僅載入了函式符號。

優點在編譯階段就完成連線,不需要單獨庫檔案。(簡單、直接、粗暴)。

1) **共享,當多個程式執行同乙個動態庫的時候,其實他們是共享的同乙份**。減少了記憶體的使用量。2)按需載入,只有當執行過程中需要使用動態庫的函式,才會去載入動態庫。減少了不必要的記憶體消耗。

缺點1) 由於每個目標程式都需要拷貝乙份連線**,所以會加重記憶體的負載。

2) 即使目標程式在執行過程中呼叫不到鏈結庫的函式(比如分支程式),靜態庫也需要載入。

1) 由於是在執行階段,才進行載入,所有會降低目標**的執行速度。

下面我用**來展示整個靜態庫和動態庫的鏈結過程

乙個標頭檔案如下:

//array operations

intmax

(int*,

int)

;int

sum(

int*

,int);

//initial array

void

initarray

(int*,

int)

;void

showarray

(int*,

int)

;

三個c檔案如下:

int

max(

int*a,

int n)

intsum

(int

*a,int n)

#include

void

showarray

(int

*a,int n)

void

initarray

(int

*a,int n)

}

#include

"staticlib.h"

#include

intmain()

對原始檔進行編譯生成.o的目標檔案

在另外乙個目錄下進行庫檔案的鏈結

#include"/home/liaozhiwen/gitspace/week5/code/staticlib/staticlib.h"

在其他目錄下鏈結動態庫有兩種方式

#include

"dylib.h"

#include

#include

#include

intmain()

f1 =

dlsym

(hd,

"initarray");

if((error=

dlerror()

)!=null

) f2 =

dlsym

(hd,

"max");

if((error=

dlerror()

)!=null

)

靜態鏈結與動態鏈結

基於gmp開發第三方庫,後者以動態鏈結庫 靜態庫?對方式發布,為了效率gmp建議對該庫採用靜態鏈結,所以,目的是生成靜態鏈結gmp庫的庫檔案 動態庫?靜態庫?一 生成可執行檔案 1.動態鏈結庫的編譯 mac和linux都是 gcc o param convention1 param conventi...

linux下的靜態鏈結和動態鏈結(一)

靜態鏈結 靜態鏈結就是,在生成可執行程式的時候,把目標檔案.o 和 靜態庫 a 使用 ld 鏈結器,鏈結生成乙個可執行程式。這是在程式載入前就完成的動作。靜態庫的生成 以 lib.c為例子,如下 include void foobar int i 使用 gcc c lib.c 命令生成 lib.o ...

動態鏈結 靜態鏈結

在linux系統中,ld鏈結器將彙編器編譯出來的目標檔案和靜態庫里的.a檔案鏈結生成可執行檔案。靜態庫中的.a檔案的 會在靜態鏈結過程中新增到可執行檔案中,可執行檔案會變得很大。與靜態鏈結不同,linux系統的ld鏈結器會將動態庫.so檔案進行符號重定位生成可執行檔案,動態庫.so檔案並不新增到可執...