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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

静态库和共享库制作

發布時間:2024/9/27 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 静态库和共享库制作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1靜態庫和共享庫

*本節就如何創建和使用程序庫進行論述。所謂“程序庫”,簡單說,就是包含了數據

和執行碼的文件。其不能單獨執行,可以作為其它執行程序的一部分來完成某些功能。庫的

存在,可以使得程序模塊化,可以加快程序的再編譯,可以實現代碼重用,可以使得程序便

于升級。程序庫可分靜態庫(static library)和共享庫(shared object)

?

A:靜態庫

是在可執行程序運行前就已經加入到執行碼中,成為執行程序的一部分;共享庫,是在

執行程序啟動時加載到執行程序中,可以被多個執行程序共享使用。

建議庫開發人員創建共享庫,比較明顯的優勢在于庫是獨立的,便于維護和更新;而靜

態庫的更新比較麻煩,一般不做推薦。然而,它們又各有優點,后面會講到。

節所講述的執行程序和庫都采用ELF(Executable and Linking Format)格式,盡管GNU

GCC工具可以處理其它格式,但不在本節的討論范圍。

靜態庫可以認為是一些目標代碼的集合。按照習慣,一般以“.a”做為文件后綴名。使

ar(archiver)命令可以創建靜態庫。因為共享庫有著更大的優勢,靜態庫已經不經常使

用。但靜態庫使用簡單,仍有使用的余地,并會一直存在。有些Unix系統,如Solaris 10

已經基本廢棄了靜態庫。

靜態庫在應用程序生成時,可以不必再編譯,節省再編譯時間。但在編譯器越來越快的

今天,這一點似乎已不重要。如果其他開發人員要使用你的程序,而你又不想給其源碼,提

供靜態庫是一種選擇。從理論上講,應用程序使用了靜態庫,要比使用動態加載庫速度快

1-5%,但實際上可能并非如此。由此看來,除了使用方便外,靜態庫可能并非一種好的選

擇。

要創建一個靜態庫,或要將目標代碼加入到已經存在的靜態庫中,可以使用以下命令:

?

ar rcs libmylib.a file1.o

?

file2.o以上表示要把目標碼file1.ofile2.o加入到靜態庫libmylib.a(ar的參數

r)。若libmylib.a不存在,會自動創建(ar的參數c)。然后更新.a文件的索引,使之包含新

加入的.o文件的內容(ar的參數s)

靜態庫創建成功后,需要鏈接到應用程序中使用。使用gcc-l選項來指定靜態庫,使

-L參數來指定庫文件的搜索路徑。比如上述例子應指定-lmylib,所有庫文件名都以lib

頭,開頭的lib在指定參數時應省略。-l-L之后都直接帶參數而不跟空格。

在使用gcc時,要注意其參數的順序。-l是鏈接器選項,一定要放在被編譯的文件名稱

之后;若放在文件名稱之前則會連接失敗,并會出現莫名其妙的錯誤。這一點切記。

?

B:共享庫

共享庫的創建比較簡單,基本有兩步。首先使用-fPIC-fpic創建目標文件,PIC

pic表示位置無關代碼,然后就可以使用以下格式創建共享庫了: gcc -share -Wl,-

soname,your_soname -o library_namefile_list library_list 下面是使用a.cb.c創建

庫的示例:

?

相關命令:

gcc –fPIC –c XX.c

gcc –fpic –c XX.c

gcc -shared -Wl,-soname,libmyab.so.1-o libmyab.so.1.0.1 a.o b.o

?

libmyab.so.1稱之為soname,

libmyab.so.1.0.1稱之為realname

libmyab.so? 稱之為linker name

?

按照共享庫的命名慣例,每個共享庫有三個文件名:real namesonamelinker

name。真正的庫文件(而不是符號鏈接)的名字是realname,包含完整的共享庫版本號。

soname是一個符號鏈接的名字,只包含共享庫的主版本號,主版本號一致即可保證庫函

數的接口一致,因此應用程序的.dynamic段只記錄共享庫的soname,只要soname一致,這個

共享庫就可以用。如libmyab.so.1libmyab.so.2是兩個主版本號不同的libmyab,有些應

用程序依賴于libmyab.so.1,有些應用程序依賴于libmyab.so.2,但對于依賴libmyab.so.1

的應用程序來說,真正的庫文件不管是libmyab.so.1.10還是libmyab.so.1.11都可以用,所

以使用共享庫可以很方便地升級庫文件而不需要重新編譯應用程序,這是靜態庫所沒有的優點。

注意libc的版本編號有一點特殊,libc-2.8.90.so的主版本號是6而不是22.8

linker name僅在編譯鏈接時使用,gcc-L選項應該指定linkername所在的目錄。有

linker name是庫文件的一個符號鏈接,有的linker name是一段鏈接腳本。例如上面的

libc.so就是一個linkername,它是一段鏈接腳本:

?

C:共享庫加載

在所有基于GNUglibc的系統中,在啟動一個ELF二進制執行程序時,一個特殊的

程序“程序裝載器”會被自動裝載并運行。在linux中,這個程序裝載器就是/lib/ldlinux.

so.X(X是版本號)。它會查找并裝載應用程序所依賴的所有共享庫。被搜索的目錄保存在/etc/ld.so.conf文件中。當然,如果程序的每次啟動,都要去搜索一番,勢必效率不

堪忍受。Linux系統已經考慮這一點,對共享庫采用了緩存管理。ldconfig就是實現這一功

能的工具,其缺省讀取/etc/ld.so.conf文件,對所有共享庫按照一定規范建立符號連接,

然后將信息寫入/etc/ld.so.cache/etc/ld.so.cache的存在大大加快了程序的啟動速

度。

?

D:案例說明:

D1:創建一個目錄,mycal

mkdir mycal

?D2:創建4c文件盒1.h,分別實現加減乘除

?add.c

?

?sub.c

mul.c

dive.c

common.h

??編寫main.c

#include <stdio.h>

#include "common.h"

?

int main(void)

{

??? printf("%d", add(5, 4));

??? return 0;

}

D3制作靜態庫(加上-fPIC后生成的目標文件和位置無關,注意要加上這個)

查看靜態庫信息:

使用靜態庫(程序扔到任何電腦都可以運行,因為靜態庫相當于包含到了靜態庫中)

gcc -Isrc main.c libmycal.a –o app(-Isrc是為類引用common.h)

ldd app命令檢測的是共享庫,不檢測靜態庫

上面的過程相當于libmycal.amain.c進行組合,生成app

??D4制作共享庫,

??移動目錄如下結構:

?

這時候生成了realname:??? libmycal.so.1.10

D5設置共享庫加載路徑

??打開共享庫路徑配置文件

??sudo vi /etc/ld.so.conf

??最后一行添加mycal路徑,截圖如下,若不配置下面的信息,它后后面的gcc執行的命令和ldd命令回報沒有找到庫的提示信息。(下面配置告訴庫所在的位置)

?

sudo ldconfig –v(輸入后輸出一堆結果,如果還是發現沒有生成libmycal.so.1,這時候要去除緩存文件/etc/ld.so.cache? 命令是:sudo rm –rf/etc/ld.so.cache

gcc main.c libmycal.so.1.10 -o app

?

ldd app查看程序運行的時候的依賴信息

如果用ldd app查看還是沒有看到依賴,要去掉依賴文件,要刪除的緩存文件是:/etc/ld.so.cache

注意:共享庫和main.c共同使用的時候,在這個過程中相當于生成了main.o,符號記錄表。app運行的時候依賴共享庫版本。

?

?

?

?



總結

以上是生活随笔為你收集整理的静态库和共享库制作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。