linux下的靜態庫與動態庫

目錄

  • 靜態庫
    • 定義:
    • 生成及使用方法:
    • 靜態庫的優缺點
  • 動態庫
    • 定義:
    • 生成及使用方法:
    • 動態庫優缺點:

靜態庫

先說說我們為什么需要庫?
當有些代碼我們大量會在程序中使用比如(scanf,printf等)這些函數我們需要在程序中頻繁使用,于是我們就把這些代碼編譯為庫文件,在需要使用時我們直接鏈接即可。

定義:

?程序在編譯時把靜態庫的代碼鏈接到可執行程序中,在代碼運行時不再需要靜態庫。(簡單理解就是把一堆 .o 文件打包到一起,當需要用到就讓我們的程序鏈接進來)

生成及使用方法:

??這里用加減乘除來舉例示意:

//創建所需文件
[root@localhost ku]# touch add.c add.h sub.c sub.h mul.c mul.h dev.c dev.h main.c 
[root@localhost ku]# ls
add.c  add.h  dev.c  dev.h  main.c  mul.c  mul.h  sub.c  sub.h
[root@localhost ku]# 
//編寫所有文件代碼
//add.c
#include"add.h"                                                                                                                       int add(int x,int y)
{return x+y;
}
//add.h#ifndef __ADD_H__
#define __ADD_H__int add(int x,int y);                                                                                                                                       #endif // __ADD_H__
//sub.c
#include"sub.h"
int sub(int x,int y)                                                                                                                  
{return x-y;
}
//sub.h
#ifndef __SUB_H__
#define __SUB_H__int sub(int x,int y); #endif // __SUB_H__  
//mul.c
#include"mul.h"int mul(int x,int y)                                                                                                                  
{return x*y;
}
//mul.h
#ifndef __MUL_H__
#define __MUL_H__int mul(int x,int y); #endif //__MUL_H__   
//dev.c
#include"dev.h"int dev(int x,int y)                                                                                                                  
{return x/y;
}
//dev.h
#ifndef __DEV_H__ 
#define __DEV_H__int dev(int x,int y);                                                                                                                 #endif // __DEV_H__
//main.c
#include<stdio.h>
#include"add.h"
#include"sub.h"
#include"mul.h"
#include"dev.h"int main()
{int a,b;scanf("%d%d",&a,&b);printf("%d + %d = %d\n",a,b,add(a,b));printf("%d - %d = %d\n",a,b,sub(a,b));printf("%d * %d = %d\n",a,b,mul(a,b));printf("%d / %d = %d\n",a,b,dev(a,b));                                                                                            return 0;
}//編譯源文件
[root@localhost ku]# ls
add.c  add.h  dev.c  dev.h  main.c  mul.c  mul.h  sub.c  sub.h
[root@localhost ku]# gcc -c *.c //把所有.c文件生成.o文件
[root@localhost ku]# ls
add.c  add.h  add.o  dev.c  dev.h  dev.o  main.c  main.o  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# rm main.o -rf  //刪除多余的.o文件
[root@localhost ku]# ls
add.c  add.h  add.o  dev.c  dev.h  dev.o  main.c  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# 
//生成靜態庫
[root@localhost ku]# ar -rc libmycal.a *.o
[root@localhost ku]# ls
add.c  add.h  add.o  dev.c  dev.h  dev.o  libmycal.a  main.c  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# 
//查看靜態庫
[root@localhost ku]# ls
add.c  add.h  add.o  dev.c  dev.h  dev.o  libmycal.a  main.c  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# ar -tv libmycal.a 
rw-r--r-- 0/0    683 Apr 26 20:46 2018 add.o
rw-r--r-- 0/0    683 Apr 26 20:46 2018 dev.o
rw-r--r-- 0/0    679 Apr 26 20:46 2018 mul.o
rw-r--r-- 0/0    687 Apr 26 20:46 2018 sub.o
[root@localhost ku]# 
//鏈接靜態庫生成可執行文件
[root@localhost ku]# ls
add.c  add.h  add.o  dev.c  dev.h  dev.o  libmycal.a  main.c  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# gcc main.c -L. -lmycal
[root@localhost ku]# ls
add.c  add.h  add.o  a.out  dev.c  dev.h  dev.o  libmycal.a  main.c  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# 
//運行結果
[root@localhost ku]# ls
add.c  add.h  add.o  a.out  dev.c  dev.h  dev.o  libmycal.a  main.c  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# ./a.out 
8 3
8 + 3 = 11
8 - 3 = 5
8 * 3 = 24
8 / 3 = 2
[root@localhost ku]# 

以上是整個靜態庫的生成及運用過程
總結起來就3步驟:

?首先將源文件編譯成目標文件:gcc –c 源文件
?生成靜態庫:ar –rc lib(庫名).a 目標文件
?使用靜態庫:gcc main.c -L(庫的路徑) -l(庫名)

靜態庫的優缺點

 優點:

?1. 省空間:linker只會復制你用到的objects。
?2. 打包簡單。

 缺點:

?1、如果靜態庫中有全局變量,那么在幾個模塊中使用,將會導致全局變量有不同的值,這是非常嚴重的問題。
?2、靜態庫編譯時,不會進行鏈接檢查,所以這么多靜態庫的問題,在生成靜態庫階段檢查不出來。
?3、幾個模塊,引用同一靜態庫,如果有一模塊沒有編譯到,會引起巨大的差異導致問題。
?4.產生大量的庫文件文件會占空間

動態庫

定義:

?程序在運行時才去鏈接動態庫的代碼,多個程序共享使用庫的代碼。
?一個與動態庫鏈接的可執行文件僅包含他用到的函數入口地址的一個表,而不是外部函數所在目標文件的機器碼。

生成及使用方法:

事例程序和上面一樣,這里只寫出操作步驟

[root@localhost ku]# ls
add.c  add.h  dev.c  dev.h  main.c  mul.c  mul.h  sub.c  sub.h
[root@localhost ku]# gcc -c -fpic *.c
// -fpic   表示編譯為位置獨立的代碼,不用此選項的話編譯后的代碼是位置相關的所以動態載入時是通過代碼拷貝的方式來滿足不同進程的需要,而不能達到真正代碼段共享的目的。
[root@localhost ku]# ls
add.c  add.h  add.o  dev.c  dev.h  dev.o  main.c  main.o  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# rm main.o -rf
[root@localhost ku]# ls
add.c  add.h  add.o  dev.c  dev.h  dev.o  main.c  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# gcc -shared -o libmycal.so *.o
[root@localhost ku]# ls
add.c  add.h  add.o  dev.c  dev.h  dev.o  libmycal.so  main.c  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# gcc main.c -L. -lmycal
//-L.   表示要連接的庫在當前目錄中
[root@localhost ku]# ls
add.c  add.h  add.o  a.out  dev.c  dev.h  dev.o  libmycal.so  main.c  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
[root@localhost ku]# ./a.out 
./a.out: error while loading shared libraries: libmycal.so: cannot open shared object file: No such file or directory
[root@localhost ku]# cp libmycal.so /lib/
//把動態庫移動到系統庫文件下
[root@localhost ku]# ls
add.c  add.h  add.o  a.out  dev.c  dev.h  dev.o  libmycal.so  main.c  mul.c  mul.h  mul.o  sub.c  sub.h  sub.o
//運行結果
[root@localhost ku]# ./a.out 
8 6
8 + 6 = 14
8 - 6 = 2
8 * 6 = 48
8 / 6 = 1
//第二種方法,更改庫路徑
[root@localhost ku]# ./main 
./main: error while loading shared libraries: libmycal.so: cannot open shared object file: No such file or directory
[root@localhost ku]# vim /etc/ld.so.conf.d/mycal.conf //在創建的文件里寫上庫的路徑
//寫好路徑之后刷新緩沖區
[root@localhost ku]# ldconfig 
//運行結果
[root@localhost ku]# ./main 
8 6
8 + 6 = 14
8 - 6 = 2
8 * 6 = 48
8 / 6 = 1

動態庫優缺點:

優點:

?1 .共享內存
?2 .獨立升級組件(插件安裝,軟件更新)
?3.可以顯示動態加載

缺點:

?1.當系統中多個應用程序都用了一個動態鏈接庫,但是要求的版本不同,這時動態鏈接庫之間就會相互干擾。
?2.性能開銷。動態鏈接庫為了做到“共享代碼,但是不共享數據”,引入了不小的開銷,調用動態鏈接庫中的函數,需要好幾次間接內存訪問才能走到函數入口,全局數據也是。

轉載于:https://www.cnblogs.com/zhonglongbo/p/8967954.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452831.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452831.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452831.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

esrgan_ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks【閱讀筆記】

針對SRGAN提出的幾點改進&#xff0c;獲得了PIRM2018視覺質量的第一名。首先是使用去掉BN層的Residual in Residual Dense Block作為網絡的basic unit。并且使用residual scling 和 smaller initialization幫助訓練更深的網絡。第二點改進是使用了Relativistic Discriminator來…

PostgreSQL Frontend/Backend protocol (通信協議)

標簽 PostgreSQL , protocol , proxy , 通信協議 背景 理解PostgreSQL的通信協議可以更好的開發類似SQL代理&#xff0c;SQL中間件&#xff0c;SQL防火墻&#xff0c;連接池等軟件。 學習資料與軟件 《PostgreSQL 讀寫分離代理 - Crunchy Proxy(base on golang)》 Postgres on …

啟動FastDFS服務,使用python客戶端對接fastdfs完成上傳測試

1.啟動tracker、storage、nginx服務&#xff1a; 啟動fdfs_trackerd&#xff1a;sudo service fdfs_trackerd start 啟動fdfs_storaged &#xff1a;sudo service fdfs_storaged start 啟動Nginx&#xff1a;sudo /usr/local/nginx/sbin/nginx 注&#xff1a;此處給出重啟服務…

軟件工程方法學

傳統方法學 傳統方法學也稱為生命周期方法學或結構化范型。它采用結構化技術(結構化分析、結構化設計和結構化實現)來完成軟件開發的各項任務&#xff0c;并使用適當的軟件工具或軟件工程環境來支持結構化技術的運用。 面向對象方法學 與傳統方法相反&#xff0c;面向對象方…

我做項目這些年的經驗

1、中國充滿大量非常敬業但不夠職業的項目經理&#xff0c;不了解這一點&#xff0c;就做不好中國的項目。 2、真正的原因往往都隱藏在表面的理由背后。 3、做項目最高境界是和用戶形成長期共生雙贏關系。 4、賣功能&#xff0c;賣利益&#xff0c;賣服務&#xff0c;賣價值…

Python學習-終端字體高亮顯示

1、采用原生轉義字符序列&#xff0c;對Windows有的版本不支持&#xff08;比如win7&#xff09;&#xff0c;完美支持Linux 實現過程&#xff1a; 終端的字符顏色是用轉義序列控制的&#xff0c;是文本模式下的系統顯示功能&#xff0c;和具體的語言無關。 轉義序列是以ESC開頭…

Win32-Application的窗口和對話框

Win32 Application&#xff0c;沒有基于MFC的類庫&#xff0c;而是直接調用C接口來編程。 一、彈出消息窗口 &#xff08;1&#xff09;最簡單的&#xff0c;在當前窗口中彈出新窗口。新窗口只有“YES”按鈕。 int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstan…

Python面試題總結(4)--數據類型(列表)

1. 已知 AList [1,2,3,1,2]&#xff0c;對 AList 列表元素去重&#xff0c;寫出具體過程。 答&#xff1a; AList [1,2,3,1,2] BList set(AList)print(BList) print(list(BList))輸出結果&#xff1a; {1, 2, 3} [1, 2, 3]2. 如何實現 “1,2,3” 變成 [“1”,“2”,“3”…

項目團隊要以十當一

如何建立起一支高效的團隊&#xff0c;并有效的管理團隊&#xff0c;一直是IT項目經理津津樂道的話題。任何一個IT項目經理對此都有自己一番不同的見解&#xff0c;根據自己團隊特點&#xff0c;項目經理正在用自身獨有的管理藝術改變著自己的團隊。項目團隊要以十當一&#xf…

Centos中配置環境變量

以Java的開發環境Jdk為例。 將jdk-9.0.1放置在/usr/local下&#xff08;UNIX規范&#xff09;&#xff0c;然后我們將jdk配置到環境變量中去。 $ mv jdk-9.0.1 /usr/local $ vim /etc/profile 修改 /etc/profile &#xff0c;最底部加入以下內容 export JAVA_HOME/usr/local/jd…

python面試題總結(5)--數據類型(字典)

1. 字典操作中 del 和 pop 有什么區別 答&#xff1a;del 可以根據索引&#xff08;元素所在位置&#xff09;來刪除的&#xff0c;沒有返回值。 pop 可以根據索引彈出一個值&#xff0c;然后可以接收它的返回值。 參考一 參考二 2. 按照字典的內的年齡排序 d1 [ {‘name’…

js下載文件 java_[Java教程]使用js實現點擊按鈕下載文件

[Java教程]使用js實現點擊按鈕下載文件0 2016-11-11 19:02:54有時候我們在網頁上需要增加一個下載按鈕&#xff0c;讓用戶能夠點擊后下載頁面上的資料&#xff0c;那么怎樣才能實現功能呢&#xff1f;這里有兩種方法&#xff1a;現在需要在頁面上添加一個下載按鈕&#xff0c;點…

underscore.js源碼研究(5)

概述 很早就想研究underscore源碼了&#xff0c;雖然underscore.js這個庫有些過時了&#xff0c;但是我還是想學習一下庫的架構&#xff0c;函數式編程以及常用方法的編寫這些方面的內容&#xff0c;又恰好沒什么其它要研究的了&#xff0c;所以就了結研究underscore源碼這一心…

人心散了、項目必然要敗

最近接手一個項目&#xff0c;是從半路上接過來的。按照常理&#xff0c;只要腦子沒被驢踢&#xff0c;是不會接人家的爛攤子的。我之所以接這個項目&#xff0c;一方面是因為這個項目中的開發人員是我部門的人&#xff08;本人是部門主管&#xff09;&#xff0c;另一方面是因…

國家自科委管文科學部認定的國內30種重要期刊

國家自科委管文科學部認定的國內30種重要期刊 A類刊物&#xff08;22種&#xff09; 1、管理科學學報&#xff08;雙月刊&#xff09; 2、系統工程理論與實踐&#xff08;月刊&#xff09; 3、管理世界&#xff08;月刊&#xff09; 4、數量經濟技術經濟研究&#xff08;月刊&a…

面向對象的四個要點

?把對象(object)作為融合了數據及在數據上的操作行為的統一的軟件構件?把所有對象都劃分成類(class)。?按照父類與子類的關系&#xff0c;把若干個相關類組成一個層次結構的系統。?對象彼此間僅能通過發送消息互相聯系。

Django二次開發對接FastDFS

1.自定義文件存儲器類 配置文件settings中加入如下配置 # 設置Django的文件存儲類、&#xff08;名字固定&#xff09; DEFAULT_FILE_STORAGEutils.fdfs.storage.FDFSStorage# 設置fdfs使用的client.conf文件路徑&#xff08;名字自己定義&#xff09; FDFS_CLIENT_CONF./util…

微信支付 java 集成案例_Spring Boot項目中集成微信支付v3

1. 前言最近忙的一批&#xff0c;難得今天有喘氣的機會就趕緊把最近在開發中的一些成果分享出來。前幾日分享了自己寫的一個微信支付V3的開發包payment-spring-boot-starter&#xff0c;就忙里偷閑完善了一波。期間給微信支付提交了6個BUG&#xff0c;跟微信支付的產品溝通了好…

單挑力扣(LeetCode)SQL題:1308. 不同性別每日分數總計

相信很多學習SQL的小伙伴都面臨這樣的困境&#xff0c;學習完書本上的SQL基礎知識后&#xff0c;一方面想測試下自己的水平&#xff1b;另一方面想進一步提升&#xff0c;卻不知道方法。 其實&#xff0c;對于技能型知識&#xff0c;我的觀點一貫都是&#xff1a;多練習、多實…