自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

《電話號碼管理系統(tǒng)》制作成靜態(tài)庫和動態(tài)庫

開發(fā) 后端
本文,一口君將繼續(xù)以之前的 電話號碼管理系統(tǒng)的項目為基礎(chǔ),給大家詳細(xì)講解如何將該項目中的函數(shù)制作成動態(tài)庫和靜態(tài)庫。

[[438801]]

一、前言

上次寫了一篇關(guān)于Makefile的文章。

《利用Makfile給多文件、多目錄C源碼建立工程》

有很多粉絲留言,有的粉絲想進(jìn)一步了解cmake的使用方法,還有的粉絲想知道如何將一些函數(shù)編譯成動態(tài)庫或者靜態(tài)庫,然后再將該庫編譯到內(nèi)存中。

一口君必須安排,本篇先講如何將一些函數(shù)編譯成動態(tài)庫或者靜態(tài)庫。

這就涉及到一個庫的概念,關(guān)于制作的庫的基礎(chǔ)知識,一口君已經(jīng)在下面這篇文章中詳細(xì)的講述了相關(guān)概念,建議大家先看下面這篇文章。

《Linux庫概念,動態(tài)庫和靜態(tài)庫概念》

本文,一口君將繼續(xù)以之前的 電話號碼管理系統(tǒng)的項目為基礎(chǔ),給大家詳細(xì)講解如何將該項目中的函數(shù)制作成動態(tài)庫和靜態(tài)庫。

《從0寫一個《電話號碼管理系統(tǒng)》的C入門項目》

二、 基礎(chǔ)知識

1) 靜態(tài)庫

所謂靜態(tài)庫,就是在靜態(tài)編譯時由編譯器到指定目錄尋找并且進(jìn)行鏈接,一旦鏈接完成,最終的可執(zhí)行程序中就包含了該庫文件中的所有有用信息,包括代碼段、數(shù)據(jù)段等。

2)動態(tài)庫

所謂動態(tài)庫,就是在應(yīng)用程序運行時,由操作系統(tǒng)根據(jù)應(yīng)用程序的請求,動態(tài)到指定目錄下尋找并裝載入內(nèi)存中,同時需要進(jìn)行地址重定向。

3)庫文件命名

靜態(tài)庫的名字一般為libxxxx.a,其中xxxx是該lib的名稱;動態(tài)庫的名字一般為libxxxx.so.x.y.z,含義如下圖所示:

4)制作庫文件常用參數(shù)

首先需要了解gcc編譯庫要用到一些參數(shù),很重要。

三、 制作靜態(tài)庫

原始文件目錄如下:

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ tree . 
  2. ├── main.c 
  3. ├── phone.c 
  4. └── phone.h 
  5.  
  6. 0 directories, 3 files 

其中 phone.c包含了對鏈表的所有的操作函數(shù) phone.h 是phone.c中所有函數(shù)的原型說明 main.c是主程序

下面我們將phone.c制作成靜態(tài)庫。

1. 把 listd.c 編譯成.o文件

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ gcc -c phone.c 

2. 使用 ar 命令生成靜態(tài)庫libadd.a

靜態(tài)庫名字遵循靜態(tài)庫命名的規(guī)則 lib + 名字 + .a

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ ar -rc libphone.a phone.o  

3. 將庫和頭文件拷貝到其他目錄下

將庫文件移動到lib目錄下

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ mkdir lib 
  2. peng@ubuntu:/mnt/hgfs/code/phone3$ mv libphone.a lib 

移動頭文件到include目錄下

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ mkdir include 
  2. peng@ubuntu:/mnt/hgfs/code/phone3$ mv phone.h include/ 

刪除phone.c

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ rm phone.c 

此處可不刪除,下面的的編譯已經(jīng)用不到該文件 刪除僅僅是為了排除干擾,有些同學(xué)會以為這個文件還會被編譯進(jìn)去

最終文件結(jié)構(gòu)如下:

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ tree ./ 
  2. ./ 
  3. ├── include 
  4. │   └── phone.h 
  5. ├── lib 
  6. │   └── libphone.a 
  7. ├── main.c 
  8. └── run 
  9.  
  10. 2 directories, 6 files 

lib include 目錄也可以是其他目錄,實際項目中庫文件和頭文件都會放到一些指定目錄下

4.編譯

值編譯main.c,會有以下錯誤提示,主要是因為phone.h

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ gcc main.c  
  2. main.c:3:19: 致命錯誤:phone.h:沒有那個文件或目錄 
  3. 編譯中斷。 

制定頭文件位置,編譯結(jié)果如下,可以看到錯誤提示,“沒有定義create”,這是因為在鏈接的時候找打不到這些函數(shù)的定義的地方

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ gcc main.c -I ./include 
  2. /tmp/cctUUKm9.o: In function `management': 
  3. main.c:(.text+0x109): undefined reference to `create
  4. main.c:(.text+0x120): undefined reference to `delete
  5. main.c:(.text+0x137): undefined reference to `search' 
  6. main.c:(.text+0x14e): undefined reference to `display' 
  7. main.c:(.text+0x167): undefined reference to `allfree' 
  8. /tmp/cctUUKm9.o: In function `main': 
  9. main.c:(.text+0x2e3): undefined reference to `init' 
  10. collect2: ld 返回 1 

最終我們執(zhí)行

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ gcc main.c -I ./include ./lib/libphone.a  

指定了頭文件和庫文件位置,執(zhí)行結(jié)果如下:

與之前運行現(xiàn)象是一樣的。

可見,使用庫的時候我們必須制定頭文件目錄以及庫目錄。

四、 制作動態(tài)庫原始文件

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ tree . 
  2. ├── main.c 
  3. ├── phone.c 
  4. └── phone.h 
  5.  
  6. 0 directories, 3 files 

1. 把phone.c編譯成動態(tài)鏈接庫libphone.so

  1. gcc -fPIC -o libphone.o -c phone.c 
  2. gcc -shared -o libphone.so libphone.o 

也可以直接使用一條命令

  1. gcc -fPIC -shared -o libphone.so phone.c 

2. 動態(tài)庫的安裝

通常動態(tài)庫拷貝到/lib下:

  1. peng@ubuntu:/mnt/hgfs/code/phone4$ sudo mv libphone.so /lib/ 
  2. [sudo] password for peng:  

刪除phone.c

  1. peng@ubuntu:/mnt/hgfs/code/phone3$ rm phone.c 

3. 編譯執(zhí)行

編譯動態(tài)庫:

  1. peng@ubuntu:/mnt/hgfs/code/phone4$ gcc main.c -lphone -o run 

此時使用我們制作的動態(tài)庫,只需要加上 -lphone即可

  1. 注意觀察編譯時動態(tài)庫的名字與庫文件對應(yīng)關(guān)系 
  2.  
  3. libphone.so<--------->-lphone  

執(zhí)行結(jié)果如下:

五、重新建立工程

下面我們將文件重新放置

當(dāng)前文件目錄如下:

  1. ./include 
  2. └── phone.h 
  3. ./Makefile  
  4. ./obj 
  5. └── Makefile 
  6. ./src 
  7. ├── main.c 
  8. └── Makefile 
  9.  
  10. 0 directories, 5 files 

并添加3個Makefile

編譯步驟如下:

聲明環(huán)境變量

  1. CC       編譯名稱 
  2. LIBS     用到的動態(tài)庫 
  3. SUBDIRS  子目錄 
  4. OBJS     src下所有的目標(biāo)文件 
  5. BIN      最終生成的可執(zhí)行程序名字 
  6. OBJS_DIR 目標(biāo)文件存放目錄 
  7. BIN_DIR  可執(zhí)行程序存儲目錄 

執(zhí)行make的默認(rèn)目標(biāo)all,依賴CHECK_DIR $(SUBDIRS)

執(zhí)行目標(biāo)CHECK_DIR ,創(chuàng)建目錄bin

執(zhí)行目標(biāo)@ ,進(jìn)入子目錄src、obj執(zhí)行子目錄的Makefile,

打印語句 echo begin compile phone!

進(jìn)入子目錄src執(zhí)行Makfile,

執(zhí)行命令

  1. @$(CC) -c main.c -I../include -o ../$(OBJS_DIR)/main.o   
  1. @ :打印該條命令 
  2. -I../include 頭文件在上一級目錄下的include中 
  3. -o ../$(OBJS_DIR)/main.o 生成的目標(biāo)文件存放在../obj/main.o 

進(jìn)入子目錄obj執(zhí)行Makfile, 目標(biāo)為../bin/phone:main.o 執(zhí)行命令

  1. @$(CC) -o $@ $^  $(LIBS) 
  1. @$(CC) 同上 
  2. $@ 表示生成的目標(biāo)文件,即../bin/phone 
  3. $^ 表示所有的依賴文件,即上面:后面目標(biāo)文件main.o 

編譯完成后就會在bin目錄下創(chuàng)建可執(zhí)行程序文件phone, 運行結(jié)果如下:

本文轉(zhuǎn)載自微信公眾號「一口Linux」

 

責(zé)任編輯:姜華 來源: 一口Linux
相關(guān)推薦

2011-06-09 11:11:35

QT 靜態(tài)庫 動態(tài)庫

2021-12-29 08:40:41

LeetCode字符串算法

2020-10-29 09:56:23

Linux靜態(tài)庫動態(tài)庫

2013-04-08 10:27:59

iOSXcode制作靜態(tài)庫

2009-06-26 10:15:27

Google語音服務(wù)

2017-01-10 13:42:18

大數(shù)據(jù)深度學(xué)習(xí)識別圖片

2010-03-04 10:17:57

Linux動態(tài)庫

2021-09-06 11:51:26

項目C語言開發(fā)

2011-07-22 16:15:11

IOS 靜態(tài)類

2015-05-13 09:57:14

C++靜態(tài)庫與動態(tài)庫

2022-03-24 23:04:37

linux靜態(tài)庫動態(tài)庫

2010-03-04 09:51:07

Linux動態(tài)庫

2020-03-11 08:52:17

Session開源通信應(yīng)用

2013-04-10 18:12:57

2021-07-12 11:15:20

黑客數(shù)據(jù)泄露網(wǎng)絡(luò)攻擊

2021-09-17 05:42:13

微信一證通查騰訊

2019-11-26 09:00:29

動態(tài)庫靜態(tài)庫運行時庫

2021-04-22 06:15:59

Linux靜態(tài)鏈接動態(tài)庫

2024-02-28 08:10:15

Linux靜態(tài)庫動態(tài)庫
點贊
收藏

51CTO技術(shù)棧公眾號