深入探討Linux靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的詳解(一看就懂)
更新時(shí)間:2013年05月27日 11:17:06 作者:
本篇文章是對(duì)Linux靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
庫(kù)從本質(zhì)上來(lái)說(shuō)是一種可執(zhí)行代碼的二進(jìn)制格式,可以被載入內(nèi)存中執(zhí)行。庫(kù)分靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)兩種。
一、靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別
1. 靜態(tài)函數(shù)庫(kù)
這類庫(kù)的名字一般是libxxx.a;利用靜態(tài)函數(shù)庫(kù)編譯成的文件比較大--空間,因?yàn)檎麄€(gè)函數(shù)庫(kù)的所有數(shù)據(jù)都會(huì)被整合進(jìn)目標(biāo)代碼中,他的優(yōu)點(diǎn)就顯而易見(jiàn)了,即編譯后的執(zhí)行程序不需要外部的函數(shù)庫(kù)支持,因?yàn)樗惺褂玫暮瘮?shù)都已經(jīng)被編譯進(jìn)去了。當(dāng)然這也會(huì)成為他的缺點(diǎn),因?yàn)槿绻o態(tài)函數(shù)庫(kù)改變了,那么你的程序必須重新編譯。
2. 動(dòng)態(tài)函數(shù)庫(kù)
這類庫(kù)的名字一般是libxxx.so;相對(duì)于靜態(tài)函數(shù)庫(kù),動(dòng)態(tài)函數(shù)庫(kù)在編譯的時(shí)候并沒(méi)有被編譯進(jìn)目標(biāo)代碼中,你的程序執(zhí)行到相關(guān)函數(shù)時(shí)才調(diào)用該函數(shù)庫(kù)里的相應(yīng)函數(shù),因此動(dòng)態(tài)函數(shù)庫(kù)所產(chǎn)生的可執(zhí)行文件比較小。由于函數(shù)庫(kù)沒(méi)有被整合進(jìn)你的程序,而是程序運(yùn)行時(shí)動(dòng)態(tài)的申請(qǐng)并調(diào)用--時(shí)間,所以程序的運(yùn)行環(huán)境中必須提供相應(yīng)的庫(kù)。動(dòng)態(tài)函數(shù)庫(kù)的改變并不影響你的程序,所以動(dòng)態(tài)函數(shù)庫(kù)的升級(jí)/更新比較方便。
二、靜態(tài)庫(kù)
(一)簡(jiǎn)單介紹
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc \
main.c src/* -I./include -L./lib -lmpi -o main
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc 為交叉編譯工具鏈
\為換行,表示下一行與當(dāng)行為同一行,‘\'后面不能有空格
main.c 為主函數(shù)
src/* 為源文件
-I后面接頭文件
-L后面接庫(kù)文件路徑路徑
-l后面接庫(kù)文件名,全名為libmpi.a
.a為靜態(tài)庫(kù)
(二)編寫(xiě)及使用靜態(tài)庫(kù)
(1)設(shè)計(jì)庫(kù)源碼 pr1.c、pr2.c 和 main.c
[bill@billstone make_lib]$ cat pr1.c
#include <stdio.h>
void print1(void)
{
printf("This is the first lib src!\n");
}
[bill@billstone make_lib]$ cat pr2.c
#include<stdio.h>
void print2(void)
{
printf("This is the second src lib!\n");
}
[bill@billstone make_lib]$ cat main.c
int main(void)
{
print1();
print2();
return 0;
}
(2) 編譯pr1.c、pr2.c 文件
[bill@billstone make_lib]$ gcc -O -c pr1.c pr2.c
[bill@billstone make_lib]$ ls -l pr*.o
-rw-rw-r-- 1 bill bill 804 4 月 15 11:11 pr1.o
-rw-rw-r-- 1 bill bill 804 4 月 15 11:11 pr2.o
(3) 鏈接靜態(tài)庫(kù)
為了在編譯程序中正確找到庫(kù)文件,靜態(tài)庫(kù)必須按照 lib[name].a 的規(guī)則命名,如下例中[name]=pr.
ar參數(shù)意義:
r:在庫(kù)中插入模塊(替換)。當(dāng)插入的模塊名已經(jīng)在庫(kù)中存在,則替換同名的模塊。
s:寫(xiě)入一個(gè)目標(biāo)文件索引到庫(kù)中,或者更新一個(gè)存在的目標(biāo)文件索引。
v:該選項(xiàng)用來(lái)顯示執(zhí)行操作選項(xiàng)的附加信息。
t:顯示庫(kù)的模塊表清單。一般只顯示模塊名。
[bill@billstone make_lib]$ ar -rsv libpr.a pr1.o pr2.o
a - pr1.o
a - pr2.o
[bill@billstone make_lib]$ ar -t libpr.a
pr1.o
pr2.o
(4) 編譯鏈接選項(xiàng)
-L 及-l 參數(shù)放在后面.其中,-L 加載庫(kù)文件路徑,-l 指明庫(kù)文件名字.
[bill@billstone make_lib]$ gcc -o main main.c -L./ -lpr //生成main
(5)執(zhí)行目標(biāo)程序
[bill@billstone make_lib]$ ./main
This is the first lib src!
This is the second src lib!
三、動(dòng)態(tài)庫(kù)(隱式調(diào)用)
(1)設(shè)計(jì)庫(kù)代碼
[bill@billstone make_lib]$ cat pr1.c
#include <stdio.h>
int p = 2;
void print(){
printf("%p:%d\n", &p, p);
printf("This is the first dll src!\n");
}
(2)生成動(dòng)態(tài)庫(kù) xxx.so
[bill@billstone make_lib]$ gcc -O -fpic -shared -o xxx.so pr1.c
[bill@billstone make_lib]$ ls -l *.so
-rwxrwxr-x 1 bill bill 6592 4 月 15 15:19 xxx.so
(3)動(dòng)態(tài)庫(kù)的隱式調(diào)用
[bill@billstone make_lib]$ cat main.c
int main()
{
print();
return 0;
}
[bill@billstone make_lib]$ gcc -o main main.c ./xxx.so
[bill@billstone make_lib]$ ./main
0x97b5d4:2
this is the first lib src!
當(dāng)動(dòng)態(tài)庫(kù)的位置發(fā)生改變時(shí), 程序?qū)o(wú)法正常運(yùn)行; 而動(dòng)態(tài)庫(kù)取代靜態(tài)庫(kù)的好處之一則是通過(guò)更新動(dòng)態(tài)庫(kù)而隨時(shí)升級(jí)庫(kù)的內(nèi)容.
一、靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別
1. 靜態(tài)函數(shù)庫(kù)
這類庫(kù)的名字一般是libxxx.a;利用靜態(tài)函數(shù)庫(kù)編譯成的文件比較大--空間,因?yàn)檎麄€(gè)函數(shù)庫(kù)的所有數(shù)據(jù)都會(huì)被整合進(jìn)目標(biāo)代碼中,他的優(yōu)點(diǎn)就顯而易見(jiàn)了,即編譯后的執(zhí)行程序不需要外部的函數(shù)庫(kù)支持,因?yàn)樗惺褂玫暮瘮?shù)都已經(jīng)被編譯進(jìn)去了。當(dāng)然這也會(huì)成為他的缺點(diǎn),因?yàn)槿绻o態(tài)函數(shù)庫(kù)改變了,那么你的程序必須重新編譯。
2. 動(dòng)態(tài)函數(shù)庫(kù)
這類庫(kù)的名字一般是libxxx.so;相對(duì)于靜態(tài)函數(shù)庫(kù),動(dòng)態(tài)函數(shù)庫(kù)在編譯的時(shí)候并沒(méi)有被編譯進(jìn)目標(biāo)代碼中,你的程序執(zhí)行到相關(guān)函數(shù)時(shí)才調(diào)用該函數(shù)庫(kù)里的相應(yīng)函數(shù),因此動(dòng)態(tài)函數(shù)庫(kù)所產(chǎn)生的可執(zhí)行文件比較小。由于函數(shù)庫(kù)沒(méi)有被整合進(jìn)你的程序,而是程序運(yùn)行時(shí)動(dòng)態(tài)的申請(qǐng)并調(diào)用--時(shí)間,所以程序的運(yùn)行環(huán)境中必須提供相應(yīng)的庫(kù)。動(dòng)態(tài)函數(shù)庫(kù)的改變并不影響你的程序,所以動(dòng)態(tài)函數(shù)庫(kù)的升級(jí)/更新比較方便。
二、靜態(tài)庫(kù)
(一)簡(jiǎn)單介紹
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc \
main.c src/* -I./include -L./lib -lmpi -o main
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc 為交叉編譯工具鏈
\為換行,表示下一行與當(dāng)行為同一行,‘\'后面不能有空格
main.c 為主函數(shù)
src/* 為源文件
-I后面接頭文件
-L后面接庫(kù)文件路徑路徑
-l后面接庫(kù)文件名,全名為libmpi.a
.a為靜態(tài)庫(kù)
(二)編寫(xiě)及使用靜態(tài)庫(kù)
(1)設(shè)計(jì)庫(kù)源碼 pr1.c、pr2.c 和 main.c
復(fù)制代碼 代碼如下:
[bill@billstone make_lib]$ cat pr1.c
#include <stdio.h>
void print1(void)
{
printf("This is the first lib src!\n");
}
[bill@billstone make_lib]$ cat pr2.c
#include<stdio.h>
void print2(void)
{
printf("This is the second src lib!\n");
}
[bill@billstone make_lib]$ cat main.c
int main(void)
{
print1();
print2();
return 0;
}
(2) 編譯pr1.c、pr2.c 文件
復(fù)制代碼 代碼如下:
[bill@billstone make_lib]$ gcc -O -c pr1.c pr2.c
[bill@billstone make_lib]$ ls -l pr*.o
-rw-rw-r-- 1 bill bill 804 4 月 15 11:11 pr1.o
-rw-rw-r-- 1 bill bill 804 4 月 15 11:11 pr2.o
(3) 鏈接靜態(tài)庫(kù)
為了在編譯程序中正確找到庫(kù)文件,靜態(tài)庫(kù)必須按照 lib[name].a 的規(guī)則命名,如下例中[name]=pr.
ar參數(shù)意義:
r:在庫(kù)中插入模塊(替換)。當(dāng)插入的模塊名已經(jīng)在庫(kù)中存在,則替換同名的模塊。
s:寫(xiě)入一個(gè)目標(biāo)文件索引到庫(kù)中,或者更新一個(gè)存在的目標(biāo)文件索引。
v:該選項(xiàng)用來(lái)顯示執(zhí)行操作選項(xiàng)的附加信息。
t:顯示庫(kù)的模塊表清單。一般只顯示模塊名。
[bill@billstone make_lib]$ ar -rsv libpr.a pr1.o pr2.o
a - pr1.o
a - pr2.o
[bill@billstone make_lib]$ ar -t libpr.a
pr1.o
pr2.o
(4) 編譯鏈接選項(xiàng)
-L 及-l 參數(shù)放在后面.其中,-L 加載庫(kù)文件路徑,-l 指明庫(kù)文件名字.
[bill@billstone make_lib]$ gcc -o main main.c -L./ -lpr //生成main
(5)執(zhí)行目標(biāo)程序
[bill@billstone make_lib]$ ./main
This is the first lib src!
This is the second src lib!
三、動(dòng)態(tài)庫(kù)(隱式調(diào)用)
(1)設(shè)計(jì)庫(kù)代碼
復(fù)制代碼 代碼如下:
[bill@billstone make_lib]$ cat pr1.c
#include <stdio.h>
int p = 2;
void print(){
printf("%p:%d\n", &p, p);
printf("This is the first dll src!\n");
}
(2)生成動(dòng)態(tài)庫(kù) xxx.so
復(fù)制代碼 代碼如下:
[bill@billstone make_lib]$ gcc -O -fpic -shared -o xxx.so pr1.c
[bill@billstone make_lib]$ ls -l *.so
-rwxrwxr-x 1 bill bill 6592 4 月 15 15:19 xxx.so
(3)動(dòng)態(tài)庫(kù)的隱式調(diào)用
復(fù)制代碼 代碼如下:
[bill@billstone make_lib]$ cat main.c
int main()
{
print();
return 0;
}
[bill@billstone make_lib]$ gcc -o main main.c ./xxx.so
[bill@billstone make_lib]$ ./main
0x97b5d4:2
this is the first lib src!
當(dāng)動(dòng)態(tài)庫(kù)的位置發(fā)生改變時(shí), 程序?qū)o(wú)法正常運(yùn)行; 而動(dòng)態(tài)庫(kù)取代靜態(tài)庫(kù)的好處之一則是通過(guò)更新動(dòng)態(tài)庫(kù)而隨時(shí)升級(jí)庫(kù)的內(nèi)容.
相關(guān)文章
C/C++使用socket實(shí)現(xiàn)判斷ip是否能連通
這篇文章主要為大家詳細(xì)介紹了C/C++如何使用socket實(shí)現(xiàn)判斷ip是否能連通,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下2023-07-07
計(jì)時(shí)器的time_t和clock_t 的兩種實(shí)現(xiàn)方法(推薦)
下面小編就為大家?guī)?lái)一篇計(jì)時(shí)器的time_t和clock_t 的兩種實(shí)現(xiàn)方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10
詳解C語(yǔ)言中的錯(cuò)誤報(bào)告errno與其相關(guān)應(yīng)用方法
這篇文章主要介紹了C語(yǔ)言中的錯(cuò)誤報(bào)告errno與其相關(guān)應(yīng)用方法,包括errno和strerror以及perror的介紹,需要的朋友可以參考下2015-08-08
C語(yǔ)言回調(diào)函數(shù)的簡(jiǎn)單運(yùn)用
回調(diào)函數(shù)就是函數(shù)指針變量作為另外一個(gè)函數(shù)的參數(shù)而使用的一種應(yīng)用情形。本文就詳細(xì)的介紹一下C語(yǔ)言回調(diào)函數(shù)的簡(jiǎn)單運(yùn)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
C++?OpenCV實(shí)現(xiàn)物體尺寸測(cè)量示例詳解
本文主要介紹了利用OpenCV對(duì)物體的尺寸進(jìn)行測(cè)量,即先定位到待測(cè)物體的位置,然后測(cè)量物體的寬高。感興趣的同學(xué)可以跟隨小編一起學(xué)習(xí)學(xué)習(xí)2022-01-01

