0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux中的靜態(tài)庫(kù)和共享庫(kù)

嵌入式攻城獅 ? 來(lái)源:嵌入式攻城獅 ? 2023-05-10 09:34 ? 次閱讀

一. 什么是庫(kù)

庫(kù)是一個(gè)二進(jìn)制文件,包含的代碼可被程序調(diào)用。例如標(biāo)準(zhǔn)C庫(kù)、數(shù)學(xué)庫(kù)、線程庫(kù)等等。庫(kù)有源碼,可下載后編譯,也可以直接安裝二進(jìn)制包。 庫(kù)是事先編譯好的,可以復(fù)用的代碼,在OS上運(yùn)行的程序基本上都要使用庫(kù)。使用庫(kù)可以提高開(kāi)發(fā)效率。Windows和Linux下庫(kù)文件的格式不兼容。Linux下包含靜態(tài)庫(kù)和共享庫(kù)。

二. 靜態(tài)庫(kù)

靜態(tài)庫(kù)有如下特點(diǎn)

編譯(鏈接)時(shí)把靜態(tài)庫(kù)中相關(guān)代碼復(fù)制到可執(zhí)行文件中

程序中包含代碼,運(yùn)行時(shí)不再需要靜態(tài)庫(kù)

程序運(yùn)行時(shí)無(wú)需加載庫(kù),運(yùn)行速度更快

占用更多磁盤(pán)和空間

靜態(tài)庫(kù)升級(jí)后,程序需要重新編譯鏈接

靜態(tài)庫(kù)的創(chuàng)建與鏈接參考如下步驟: 第一步:確定庫(kù)中函數(shù)的功能、接口

第二步:編寫(xiě)庫(kù)源碼

/****hello.c****/
#include
#include"hello.h"

voidhello(void){
   printf("helloAndyxi
");
}
/****hello.h****/
#ifndef_HELLO_H_
#define_HELLO_H_

voidhello(void);

#endif

第三步:編譯生成目標(biāo)文件

linux@linux:~/andy/lib$ls
hello.chello.h
linux@linux:~/andy/lib$gcc-chello.c-Wall
linux@linux:~/andy/lib$ls
hello.chello.hhello.o

第四步:創(chuàng)建靜態(tài)庫(kù)

linux@linux:~/andy/lib$ls
hello.chello.hhello.o
linux@linux:~/andy/lib$arcrslibhello.ahello.o//使用arcrs命令創(chuàng)建靜態(tài)庫(kù)
linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.a   //注意libhello.a是庫(kù)文件名,hello是庫(kù)名
linux@linux:~/andy/lib$nmlibhello.a   //使用nm命令可查看庫(kù)中符號(hào)信息

hello.o:
00000000Thello
Uputs

第五步:編寫(xiě)應(yīng)用程序

/****test.c****/
#include
#include"hello.h"

intmain(intargc,constchar*argv[]){
   hello();
return0;
}

第六步:編譯應(yīng)用程序并鏈接靜態(tài)庫(kù)

linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.atest.c
linux@linux:~/andy/lib$gcc-otesttest.c-L.-l hello //使用-L.-l+庫(kù)名鏈接靜態(tài)庫(kù)
linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.atesttest.c
linux@linux:~/andy/lib$./test
helloAndyxi

由于使用的是靜態(tài)庫(kù),編譯后相關(guān)代碼已經(jīng)復(fù)制到可執(zhí)行文件中。刪除靜態(tài)庫(kù),不影響程序執(zhí)行

linux@linux:~/andy/lib$ls
hello.chello.hhello.olibhello.atesttest.c
linux@linux:~/andy/lib$rmlibhello.a
linux@linux:~/andy/lib$ls
hello.chello.hhello.otesttest.c
linux@linux:~/andy/lib$./test
helloAndyxi

三. 共享庫(kù)

共享庫(kù)有如下特點(diǎn):

編譯(鏈接)時(shí)僅記錄用到哪個(gè)共享庫(kù)中的哪個(gè)符號(hào),不復(fù)制共享庫(kù)中相關(guān)代碼

程序不包含庫(kù)中代碼,尺寸小

多個(gè)程序可共享一個(gè)庫(kù)

程序運(yùn)行時(shí)需要加載庫(kù)

庫(kù)升級(jí)方便,無(wú)需重新編譯程序

使用更加廣泛

共享庫(kù)的創(chuàng)建與鏈接參考如下步驟: 第一步:確定庫(kù)中函數(shù)的功能、接口

第二步:編寫(xiě)庫(kù)源碼

/****hello.c****/
#include

voidhello(void){
   printf("helloworld
");
   return;
}
/****bye.c****/
#include

voidbye(void){
   printf("bye!
");
   return;
}
/****共享庫(kù)頭文件common.h****/
#ifndef__COMMON_H__
#define__COMMON_H__

voidhello(void);
voidbye(void);

#endif

第三步:編譯生成目標(biāo)文件

linux@linux:~/andy/lib/share$ls
bye.ccommon.hhello.c
linux@linux:~/andy/lib/share$gcc-c-fPIC*.c-Wall
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.o

fPIC選項(xiàng):告訴編譯器生成位置無(wú)關(guān)代碼

位置無(wú)關(guān)代碼:生成的".o文件"文件中的代碼可以被加載到任意的地址執(zhí)行。編譯時(shí)用到了相對(duì)尋址而不是絕對(duì)尋址

第四步:創(chuàng)建共享庫(kù)common

linux@linux:~/andy/lib/share$gcc-shared-olibcommon.so.1hello.obye.o
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.so.1

shared選項(xiàng):告訴編譯器生成一個(gè)共享庫(kù)

生成的共享庫(kù)的文件名叫"libcommon.so.1",其中".so"表示這是一個(gè)共享庫(kù),".1"表示這個(gè)庫(kù)的版本是1

符號(hào)鏈接文件命名規(guī)則:lib<庫(kù)名>.so

第五步:編寫(xiě)應(yīng)用程序

/****test.c****/
#include
#include"common.h"

intmain(intargc,constchar*argv[]){
   hello();
   bye();
return0;
}

第六步:編譯應(yīng)用程序并鏈接共享庫(kù)

#****為共享庫(kù)文件創(chuàng)建鏈接文件****#
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.so.1test.c
linux@linux:~/andy/lib/share$ln-slibcommon.so.1libcommon.so //ln-s創(chuàng)建符號(hào)鏈接
linux@linux:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.solibcommon.so.1test.c

#****編譯應(yīng)用程序并鏈接共享庫(kù)****#
linux@linux:~/andy/lib/share$gcc-otesttest.c-L.-lcommon
linux@linux-:~/andy/lib/share$ls
bye.cbye.ocommon.hhello.chello.olibcommon.solibcommon.so.1testtest.c

gcc -o test test.c -L. -lcommon:可見(jiàn)此處共享庫(kù)和靜態(tài)庫(kù)用法相同;GCC在鏈接時(shí)首先找共享庫(kù),如果共享庫(kù)不存在,則鏈接靜態(tài)庫(kù),如果靜態(tài)庫(kù)也找不到,則報(bào)錯(cuò)

加"-static"選項(xiàng)后,編譯器會(huì)直接去找靜態(tài)庫(kù)

共享庫(kù)的加載:如果完成上述步驟后就執(zhí)行程序,會(huì)報(bào)如下錯(cuò)誤

linux@linux:~/andy/lib/share$./test
./test:errorwhileloadingsharedlibraries:libcommon.so:cannotopensharedobjectfile:Nosuchfileordirectory

出錯(cuò)原因:因?yàn)槌绦蜴溄拥氖枪蚕韼?kù),并沒(méi)有復(fù)制共享庫(kù)中的代碼,程序在執(zhí)行時(shí)會(huì)去加載用到的共享庫(kù),加載時(shí)會(huì)去缺省路徑(比如"/lib","/usr/lib")下尋找共享庫(kù),但是我們創(chuàng)建的庫(kù)在當(dāng)前目錄下,并不在系統(tǒng)庫(kù)的搜索路徑里,所以在執(zhí)行時(shí)找不到共享庫(kù),因此報(bào)錯(cuò)

創(chuàng)建好共享庫(kù)后還需要添加共享庫(kù)加載路徑

第七步:加載共享庫(kù)并執(zhí)行程序

linux@linux:~/andy/lib/share$exportLD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
linux@linux:~/andy/lib/share$./test
helloworld
bye!

export 用于將原來(lái)的環(huán)境變量導(dǎo)出

":"前面的"$LD_LIBRARY_PATH"是引用原先的值;":"后面的"."是追加了當(dāng)前目錄;還可追加其余共享庫(kù)的路徑,要用":"隔開(kāi)

此方法是臨時(shí)的,只對(duì)當(dāng)前終端有效。當(dāng)重新打開(kāi)一個(gè)終端再執(zhí)行改程序時(shí)又會(huì)報(bào)錯(cuò)

為了讓系統(tǒng)能找到要加載的共享庫(kù),通常由三種方法:

把庫(kù)拷貝到/usr/lib和/lib目錄下

在LD_LIBRARY_PATH環(huán)境變量中添加庫(kù)所在路徑

添加/etc/ld.so.conf.d/*.conf文件,執(zhí)行 ldconfig刷新

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11479

    瀏覽量

    213073
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4374

    瀏覽量

    64425
  • 靜態(tài)庫(kù)
    +關(guān)注

    關(guān)注

    0

    文章

    21

    瀏覽量

    7594
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    676

    瀏覽量

    33834
  • 共享庫(kù)
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    5664

原文標(biāo)題:Linux 中的靜態(tài)庫(kù)和共享庫(kù)

文章出處:【微信號(hào):嵌入式攻城獅,微信公眾號(hào):嵌入式攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    動(dòng)態(tài)庫(kù)靜態(tài)庫(kù)的區(qū)別

    一、什么是庫(kù)本質(zhì)上來(lái)說(shuō)庫(kù)是一種可執(zhí)行代碼的二進(jìn)制形式,可以***作系統(tǒng)載入內(nèi)存執(zhí)行。二、庫(kù)的種類linux下的庫(kù)有兩種:靜態(tài)
    發(fā)表于 05-26 17:22

    Linux下動(dòng)態(tài)庫(kù)靜態(tài)庫(kù)的制作及使用

    可執(zhí)行代碼的二進(jìn)制格式,可以被載入內(nèi)存執(zhí)行。根據(jù)鏈接時(shí)期的不同,庫(kù)又有:靜態(tài)庫(kù)共享庫(kù)(動(dòng)態(tài)
    發(fā)表于 11-18 17:05

    Linux靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的制作與使用

    什么是靜態(tài)函數(shù)庫(kù)?動(dòng)態(tài)函數(shù)庫(kù)又是什么?linux靜態(tài)函數(shù)庫(kù)是怎樣創(chuàng)建并使用的?動(dòng)態(tài)函數(shù)庫(kù)是怎樣創(chuàng)建并使用的?
    發(fā)表于 04-26 06:45

    Linux系統(tǒng)共享庫(kù)編程

    一、說(shuō)明 類似Windows系統(tǒng)的動(dòng)態(tài)鏈接庫(kù),Linux也有相應(yīng)的共享庫(kù)用以支持代碼的復(fù)用
    發(fā)表于 09-13 16:49 ?24次下載

    Linux靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)共享庫(kù))的制作與使用

    Linux靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)共享庫(kù))的制作與使用Linux
    發(fā)表于 07-09 14:39 ?1272次閱讀

    linux靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)分析

    的二進(jìn)制是不兼容的。 本文僅限于介紹linux下的庫(kù)。 2.庫(kù)的種類 linux下的庫(kù)有兩種:靜態(tài)
    發(fā)表于 11-02 10:12 ?1次下載

    Linux靜態(tài)元件庫(kù)資料合集免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是Linux靜態(tài)元件庫(kù)資料合集免費(fèi)下載
    發(fā)表于 12-28 17:04 ?6次下載

    你知道linux 靜態(tài)庫(kù)共享庫(kù)?

    靜態(tài)鏈接庫(kù)和動(dòng)態(tài)鏈接庫(kù)的區(qū)別在于,主程序在運(yùn)行前,靜態(tài)鏈接庫(kù)的鏈接固定寫(xiě)入在程序,而動(dòng)態(tài)鏈接
    發(fā)表于 04-26 16:46 ?3034次閱讀

    講解Linux虛擬機(jī)之使用動(dòng)態(tài)庫(kù)靜態(tài)庫(kù)

    了解 Linux 如何使用庫(kù),包括靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的差別,有助于你解決依賴問(wèn)題。
    發(fā)表于 05-06 17:05 ?2442次閱讀
    講解<b class='flag-5'>Linux</b>虛擬機(jī)之使用動(dòng)態(tài)<b class='flag-5'>庫(kù)</b>和<b class='flag-5'>靜態(tài)</b><b class='flag-5'>庫(kù)</b>

    C++基礎(chǔ)語(yǔ)法知識(shí)之鏈接裝載庫(kù)Linux共享庫(kù)

    Linux共享庫(kù)(Shared Library) Linux 下的共享庫(kù)就是普通的 ELF
    的頭像 發(fā)表于 11-01 10:15 ?3131次閱讀

    嵌入式Linux下動(dòng)態(tài)庫(kù)靜態(tài)庫(kù)使用

    以下主要介紹Linux 下動(dòng)態(tài)庫(kù)、靜態(tài)庫(kù)、如何使用已有的動(dòng)態(tài)庫(kù), 以及如何制作一個(gè)動(dòng)態(tài)庫(kù)。
    發(fā)表于 11-01 16:57 ?1次下載
    嵌入式<b class='flag-5'>Linux</b>下動(dòng)態(tài)<b class='flag-5'>庫(kù)</b>和<b class='flag-5'>靜態(tài)</b><b class='flag-5'>庫(kù)</b>使用

    Linux下動(dòng)態(tài)庫(kù)靜態(tài)庫(kù)制作與調(diào)用

    靜態(tài)庫(kù)是指在應(yīng)用,有一些公共代碼需要反復(fù)使用,就把這些代碼編譯為“庫(kù)”文件;在鏈接步驟,連接器將從庫(kù)
    的頭像 發(fā)表于 08-24 15:03 ?4254次閱讀
    <b class='flag-5'>Linux</b>下動(dòng)態(tài)<b class='flag-5'>庫(kù)</b>和<b class='flag-5'>靜態(tài)</b><b class='flag-5'>庫(kù)</b>制作與調(diào)用

    Linux開(kāi)發(fā)_動(dòng)態(tài)靜態(tài)庫(kù)創(chuàng)建與Makefile規(guī)則

    介紹Linux靜態(tài)庫(kù)、動(dòng)態(tài)庫(kù)創(chuàng)建方式、完成靜態(tài)庫(kù)、動(dòng)態(tài)庫(kù)
    的頭像 發(fā)表于 09-17 15:41 ?1695次閱讀

    動(dòng)態(tài)庫(kù)靜態(tài)庫(kù)的制作步驟

    庫(kù)是一種可執(zhí)行的二進(jìn)制文件,是編譯好的代碼。使用庫(kù)可以提高開(kāi)發(fā)效率。在 Linux 下有靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)
    的頭像 發(fā)表于 07-27 11:00 ?1067次閱讀

    如何查看linux程序共享庫(kù)呢?

    linux系統(tǒng),程序通常需要依賴于外部庫(kù)來(lái)正常工作。這些庫(kù)可以直接編譯到程序,也可以從共享
    的頭像 發(fā)表于 08-28 09:11 ?1932次閱讀
    如何查看<b class='flag-5'>linux</b>程序<b class='flag-5'>共享</b><b class='flag-5'>庫(kù)</b>呢?

    電子發(fā)燒友

    中國(guó)電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品