一、首先我們來說一下庫的基礎概念:
在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檔案並不新增到可執...