函數(shù)庫其實就是一些寫好的函數(shù)集合,方便別人的復用。實現(xiàn)的封裝之后,最終的目的都是給別人調用。
庫的形式分:動態(tài)鏈接庫和靜態(tài)鏈接庫。
優(yōu)點:
(1)庫文件都是被編譯好的二進制文件,別人看不到源代碼,可以保持保密;(2)同時不會因為不小心被修改出現(xiàn)問題,便于維護。
其實就是將多函數(shù),做編譯但是不鏈接生成的 .o 文件,使用 ar 工具打包為 .a 的文件。編譯的階段,當調用這些庫的時候,鏈接器就會去 .a 的庫文件中拿出被調用的那個函數(shù)的 .o 文件進行鏈接到而執(zhí)行的程序。這個過程是將庫函數(shù)的 .o 的文件與主函數(shù)的文件一起打包成為一個可執(zhí)行的文件,所以這個可執(zhí)行的文件就會很大。加載到內存的時候,也是會占據(jù)很大的空間,生命周期是整個程序的生命周期。
缺點: 當多個可執(zhí)行的文件包含了相同的庫文件的時候,比如 a,b 都包含了 printf 這個庫,那么內存就被會同時存在兩個相同的庫,多么的浪費內存啊。
動態(tài)鏈接庫的鏈接方式是,在編譯的階段是不會將涉及到的庫文件鏈接到代碼中的,而是制作了一個標記;當程序運行的時候需要相應的庫文件的時候,就將相應的庫文件加載到內存進行使用,不用的時候就進行釋放。所以使用動態(tài)鏈接庫的時候,而到的可執(zhí)行的文件會比較的小,避免了空間的浪費。
優(yōu)點:動態(tài)庫是在需要的時候才被進行才入到內存,所以解決了動態(tài)庫的更新、部署、發(fā)布代碼上面的麻煩,用戶只需要加載新的動態(tài)庫,做增量更新就可以了。
gcc 中編譯鏈接默認使用的是動態(tài)鏈接的方式的,所以當要使用靜態(tài)鏈接的方式的時候,就需要添加: -static
windows:
靜態(tài)庫 : .lib 文件
動態(tài)庫 : .dll 文件
自己制作靜態(tài)庫,最主要的是生成自己的 .a 文件和 .h 文件。
test.c 就是我們制作庫函數(shù)材料:
定義了兩個函數(shù)的實現(xiàn)方式。
上一步實現(xiàn)了 test.c 的實現(xiàn)的方式,所以我們必須有與庫材料同名的頭文件。
test.h
頭文件其實就是將實現(xiàn)的材料的函數(shù)原型進行聲明。記得是原型。
(3)生成庫文件
Makefile:
將 test.c 生成為 .o 的文件,這里使用了: -c 進行了指定為只是進行編譯,但是沒有進行鏈接。記住 c 是小寫的哦。
使用 ar 打包工具生成 libtest.a。這里的庫的名字不能是隨意進行取名的,因為文件是 test.o 的文件,所以庫的名字只能是 libtest.a,也就是lib + 文件的名字。
上面的步驟已經(jīng)得到了我們需要的 .h 和 .a 的文件。
自己的代碼:
編譯的方式:
-L : 指定庫文件的路徑,這里指定的是絕對的路徑,當前路徑的話,可以用電進行表示。
-ltest : 執(zhí)行庫的名字。上面我們生成的庫的名字是 libtest.a,而我們這里是使用了小寫的 l 代表了 lib,所以就可以使用 libtest 去代替。
nm 命令是可以查看一個動態(tài)庫和靜態(tài)庫里面的符號信息。、
可見庫里面只是包含了 一個 test.o(一般的庫文件都是包含大量的 .o 的文件),而 test.o 里面只是包含了兩個 函數(shù)。
制作的材料使用上面的 test.c,頭文件的話也是 test.h,這里都不做修改。
Makefile:
-fPIC :執(zhí)行生成的 .o 的文件是位置無關碼的。
-share : 以生成動態(tài)鏈接庫
這樣就得到了 .h 和 .so庫文件了。
編譯一次性成功,但是運行的時候確實報錯了。原因是:動態(tài)鏈接庫是實現(xiàn)動態(tài)加載的,當需要調用相關庫的時候,去加載相應的庫,而默認加載動態(tài)庫的路徑是系統(tǒng)的固定路徑,所以解決的辦法:
方法一:將自己的動態(tài)庫放到系統(tǒng)的目錄: /usr/lib/ 目錄里面。
方法二:添加 LD_LIBRARY_PATH。 LD_LIBRARY_PATH 是系統(tǒng)加載路的路徑,操作系統(tǒng)加載固定目錄的時候,先回去 LD_LIBRARY_PATH 去尋找相應的庫文件,當沒有找到的時候采取固定的目錄: /usr/lib/ 下尋找。、
通過 export 命令添加了庫尋找的路徑。
ldd 命令的作用是查看文件依賴哪些的共享庫,并且查看這些庫是否可以被找到,能被解析。
可見,我們的可執(zhí)行的文件是依賴于四個庫。上面的意思是這四個庫都可以被找到,都是指向于數(shù)字地址,。當沒有找到這些庫的時候,就會出現(xiàn): n、
not found。
聯(lián)系客服