日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux 动态库建立,浅析linux下静态库和动态库的建立和使用

發(fā)布時(shí)間:2024/9/30 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 动态库建立,浅析linux下静态库和动态库的建立和使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在粵嵌學(xué)了很多知識,我們把常用的公用函數(shù)放在一起做成一個(gè)函數(shù)庫,可以供其他程序共同使用,函數(shù)庫本質(zhì)上說,是一個(gè)可執(zhí)行代碼的二進(jìn)制形式,可被操作系統(tǒng)載入內(nèi)存執(zhí)行。linux下的庫分為兩種:靜態(tài)庫,后綴名為

.a和動(dòng)態(tài)庫后綴名為.so(共享庫);

兩者的區(qū)別是:

靜態(tài)庫和動(dòng)態(tài)庫被載入應(yīng)用程序的時(shí)刻不同,調(diào)用靜態(tài)庫函數(shù)的應(yīng)用程序在編譯時(shí),會(huì)把靜態(tài)庫的代碼鏈接到目標(biāo)代碼中(也就是應(yīng)用程序的代碼中),因此程序所占內(nèi)存比較大,以后運(yùn)行此目標(biāo)程序時(shí)不再需要靜態(tài)庫;而動(dòng)態(tài)庫在程序編譯時(shí)不會(huì)鏈接到目標(biāo)代碼中,動(dòng)態(tài)庫只有在程序執(zhí)行時(shí),才被載入內(nèi)存,因此目標(biāo)程序所占空間小(如下圖),但是目標(biāo)程序每次運(yùn)行還要依賴這個(gè)動(dòng)態(tài)庫,所以如果這個(gè)動(dòng)態(tài)庫不存在了,則程序無法運(yùn)行。

那么,linux下是如何使用和創(chuàng)建自己的函數(shù)庫呢?我們以一個(gè)sin.c函數(shù)計(jì)算為例:

#include

int main(void)

{

float value;

value = sin ( 3.14 / 2 );

printf("%f\n",value);

}

我們編譯這個(gè)函數(shù):

gcc -o sin sin.c

出現(xiàn)以下錯(cuò)誤信息:

sin.c: In function 'main':

sin.c:5: warning: incompatible implicit declaration of built-in

function 'sin'

/tmp/cciDlilg.o(.text+0x2c): In function `main':

sin.c: undefined reference to `sin'

collect2: ld returned 1 exit status

‘undefined reference to sin’,說的是沒有 sin 的相關(guān)定義參考值!這是因?yàn)?C 語言里面的 sin

函示是寫在 libm.so

這個(gè)函式庫中,而我們并沒有在原始碼里面加入相關(guān)的說明,所以當(dāng)然就需要在編譯與連結(jié)的時(shí)候?qū)⑦@個(gè)函式庫給他連結(jié)進(jìn)執(zhí)行檔里面,所以可以這樣做:

gcc -o sin sin.c -L/usr/lib -lm

"-L"是指定libm.so庫所在的路徑(linux函數(shù)庫在/uer/lib中),-l是指定庫函數(shù)的名字,

“m ” :則是 libm.so 這個(gè)函式庫,其中, lib 與副檔名(.a 或 .so)不需要寫。

太棒了!終于編譯成功了。現(xiàn)在看看如何建立自己的庫!所有庫的都是由.o文件生成的,我們再看一個(gè)簡單的例子,先寫出以下三個(gè)程序:程序hello.c:

#include

void hello(const char *name)

{

printf("hello:%s!\n",name);

}

程序hello.h:

#ifdef HELLO_H

#define HELLO_H

void hello(const char *name)

#endif

程序main.c:

#include

int main()

{

hello("you are a good boy!");

return 0;

}

hello.c是我們要做的函數(shù)庫的源文件,里面包含庫函數(shù)hello();?hello.h是該庫函數(shù)的頭文件,main.c為測試這個(gè)函數(shù)庫的程序;?如果我們這樣編譯main.c程序,?gcc -o main

main.c?會(huì)出現(xiàn)以下錯(cuò)誤:?main.c:1:18:

error: hello.h: 沒有那個(gè)文件或目錄提示找不到頭文件,因?yàn)閔ello.h是我們自己寫的頭文件,標(biāo)準(zhǔn)c函數(shù)庫里面沒有這個(gè)頭文件,我們在編譯時(shí)加一個(gè)參數(shù)-I.,指明hello.h在當(dāng)前目錄路徑下(如果你放在其他路徑下,就改為:-I/頭文件路徑名):

gcc -o?main main.c -I.

不要開心太早,這時(shí)還會(huì)有錯(cuò)誤:

/tmp/ccr2NRXk.o: In function `main':

main.c:(.text+0x11): undefined reference to `hello'

collect2: ld returned 1 exit status

這個(gè)錯(cuò)誤是不是跟上面編譯sin函數(shù)時(shí)出現(xiàn)的“sin.c:

undefined reference to `sin”是不是很像,沒錯(cuò),找不到庫函數(shù)hello;因?yàn)槿笔〉?uer/lib里面沒有這個(gè)庫函數(shù),這時(shí)候我們就要自己做一個(gè)函數(shù)庫!先做一個(gè)靜態(tài)庫:1:將hello.c編譯成hello.o文件,無論靜態(tài)庫還是動(dòng)態(tài)庫都由.o文件生成:

gcc -c hello.c

2:由.o文件來創(chuàng)建靜態(tài)庫:靜態(tài)庫文件名的命名規(guī)范是以lib為前綴,緊接著跟靜態(tài)庫名,擴(kuò)展名為.a。例如:我們將創(chuàng)建的靜態(tài)庫名為myhello,則靜態(tài)庫文件名就是libmyhello.a。在創(chuàng)建和使用靜態(tài)庫時(shí),需要注意這點(diǎn)。創(chuàng)建靜態(tài)庫用ar命令。

ar crv libmyhello.a

hello.o這是如果你看到libmyhello.a文件,說明你的靜態(tài)庫已經(jīng)創(chuàng)建成功了!現(xiàn)在我們看看如何使用這個(gè)靜態(tài)庫:在程序main.c中,我們包含了靜態(tài)庫的頭文件hello.h,然后在主程序main中直接調(diào)用公用函數(shù)hello。下面先生成目標(biāo)程序hello,然后運(yùn)行hello程序看看結(jié)果如何。

gcc -o main?main.c -L. -lmyhello

./main

hello:you are a good boy!

運(yùn)行成功,由于靜態(tài)庫是在編譯的鏈接到目標(biāo)程序中的,編譯成功后就不依賴靜態(tài)庫,此時(shí)你可以刪除靜態(tài)庫libmyhello.a,在運(yùn)行以下程序驗(yàn)證上面的說法!我們再來看看如何創(chuàng)建一個(gè)動(dòng)態(tài)庫:

1:動(dòng)態(tài)庫的命名個(gè)靜態(tài)庫一樣,也是在動(dòng)態(tài)庫名增加前綴lib,但其文件擴(kuò)展名為

.so。我們用gcc創(chuàng)建一個(gè)動(dòng)態(tài)庫名為myhello的文件:

gcc -shared -fPCI -o libmyhello.so hello.o

2:現(xiàn)在使用剛創(chuàng)建成功的libmyhello.so:在程序中使用動(dòng)態(tài)庫和使用靜態(tài)庫完全一樣,也是在使用到這些公用函數(shù)的源程序中包含這些公用函數(shù)的原型聲明,然后在用gcc命令生成目標(biāo)文件時(shí)指明動(dòng)態(tài)庫名進(jìn)行編譯。我們先運(yùn)行g(shù)cc命令生成目標(biāo)文件,再運(yùn)行它看看結(jié)果。

gcc -o main main.c -L. -lmyhello

./main

./main: error while loading shared libraries: libmyhello.so:

cannot open shared object file: No such file or directory

錯(cuò)

誤提示找不到動(dòng)態(tài)庫文件libmyhello.so。程序在運(yùn)行時(shí),會(huì)在/usr/lib和/lib等目錄中查找需要的動(dòng)態(tài)庫文件。若找到,則載入動(dòng)態(tài)

庫,否則將提示類似上述錯(cuò)誤而終止程序運(yùn)行。我們將文件libmyhello.so復(fù)制到目錄/usr/lib中,再試試。

# mv libmyhello.so /usr/lib

# ./main

Hello:you are a good boy!

成功。這也進(jìn)一步說明了動(dòng)態(tài)庫在程序運(yùn)行時(shí)是需要的。

一般情況下,我們?yōu)榱吮3?usr/liub庫的原始性,我們不把自己創(chuàng)建的動(dòng)態(tài)庫放在目錄/usr/lib中,而是在其他路徑下自己建立一個(gè)目錄,然后把我們自己的函數(shù)庫集中放在里面,這是編譯時(shí)就要修改環(huán)境變量LD_LIBRARY_PATH,指向自己創(chuàng)建的函數(shù)庫的路徑,在linux下可以用export命令來設(shè)置和查看這個(gè)環(huán)境變量;

另外:當(dāng)靜態(tài)庫和動(dòng)態(tài)庫同名時(shí),gcc將優(yōu)先使用動(dòng)態(tài)庫,可以自己驗(yàn)證以下!

總結(jié)

以上是生活随笔為你收集整理的linux 动态库建立,浅析linux下静态库和动态库的建立和使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。