1. 程式人生 > >打包生成一個靜態庫&動態庫

打包生成一個靜態庫&動態庫

靜態庫和動態庫之間不同之處就在於程式碼被載入的時刻不同。靜態庫的程式碼在編譯過程中已經被載入可執行程式,因此體積比較大;動態庫(共享庫)的程式碼是在可執行程式執行時被載入記憶體的,在編譯過程中僅簡單的引用,因此程式碼體積較小

一、靜態庫和動態庫的定義
1、靜態庫(.a)
程式在編譯連結的時候把庫的程式碼連結到可執行檔案中,程式執行的時候將不再需要靜態庫

下面打包實現一下靜態庫:

//add.h
#ifndef __ADD_H__
#define __ADD_H__
int add(int a, int b);
#endif  //__ADD_H__

//add.c
#include "add.h"
int add(int a, int b) { return a+b; } //sub.h #ifndef __SUB_H__ #define __SUB_H__ int sub(int a, int b); #endif //__SUB_H__ //sub.c #include "sub.h" int sub(int a, int b) { return a-b; } //main.c #include <stdio.h> #include "add.h" #include "sub.h" int main() { int a = 2; int
b = 3; printf("add(2,3)=%d\n", a, b, add(a,b)); a = 10; b = 5; printf("sub(10,5)=%d\n",a, b, sub(a,b)); }

這裡寫圖片描述

* 注:(1) 由原始檔編譯生成一堆 .o檔案,每個 .o檔案裡都包含這個這個編譯單元的符號表
      (2)ar命令將很多 .o轉換為.a,成靜態庫
      (3)測試目標檔案生成之後,刪掉靜態庫,程式照樣可以執行

這樣打包使用靜態庫就完成啦!!!

庫搜尋路徑:

* 從左至右搜尋-L指定的目錄
* 由環境變數指定的目錄(LIBRARY_PATH)
* 由系統指定的目錄>*/usr/lib>*/usr/local/lib

2、動態庫(.os)由gcc加特定引數編譯產生
程式在執行的時候才去連結動態庫的程式碼,多個程式共享使用庫的程式碼。動態庫檔名命名規範和靜態庫檔名命名規範類似,也是在動態庫名增加字首lib。
eg:建立的動態庫名為mymath,則動態庫檔名libmymath.so。
(1)由.o檔案建立動態庫檔案
這裡寫圖片描述

// gcc -shared -fPCI -o libmymath.so math.o

shared:表示生成共享庫格式
fPIC:產生位置無關碼

(2)使用動態庫

//  gcc main.o -o main -L. -l庫名

-l:連結動態庫,只要庫名即可
-L:連結庫所在的路程

3、靜態庫和動態庫的比較
因為靜態庫被連結後庫就直接被嵌入可執行檔案中了,這樣就會帶來以下幾個麻煩:
(1)系統空間被浪費,倘若多個程式連結同一個庫,則每一個生成的可執行檔案就都會有一個庫的副本,因此就會浪費系統空間。(2)當我們發現庫中有bug時,這就比較麻煩了,就要把連結該庫的程式都找出來,然後重新編譯

但是嘞,wuli動態庫就剛好巧妙的彌補了靜態庫的弊端。因為動態庫是在程式執行時被連結的,所以磁碟上必須保留一份副本,因此節約了磁碟空格。若果發現bug,我們只需用新的庫將原來的替換掉就可以了