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

實(shí)例詳解 - 靜態(tài)鏈接在 Linux 上的工作原理

系統(tǒng) Linux
在本文中,我將解釋如何創(chuàng)建靜態(tài)鏈接的可執(zhí)行文件。

了解如何使用靜態(tài)庫(kù)將多個(gè) C 對(duì)象文件組合成一個(gè)可執(zhí)行文件。

使用 C 編寫(xiě)的應(yīng)用程序代碼通常有多個(gè)源文件,但最終您需要將它們編譯成一個(gè)可執(zhí)行文件。

您可以通過(guò)兩種方式做到這一點(diǎn):通過(guò)創(chuàng)建靜態(tài)庫(kù)或動(dòng)態(tài)庫(kù)(也稱(chēng)為共享庫(kù))。這兩種類(lèi)型的庫(kù)在創(chuàng)建和鏈接方式方面有所不同。您選擇使用哪個(gè)取決于您的用例。

在本文中,我將解釋如何創(chuàng)建靜態(tài)鏈接的可執(zhí)行文件。

使用帶有靜態(tài)庫(kù)的鏈接器

鏈接器是將程序的多個(gè)部分組合在一起并重新組織它們的內(nèi)存分配的命令。

鏈接器的功能包括:

  • 整合程序的所有部分
  • 找出一個(gè)新的記憶組織,使所有的部分組合在一起
  • 恢復(fù)地址以便程序可以在新的內(nèi)存組織下運(yùn)行
  • 解析符號(hào)引用

作為所有這些鏈接器功能的結(jié)果,創(chuàng)建了一個(gè)稱(chēng)為可執(zhí)行文件的可運(yùn)行程序。

通過(guò)將程序中使用的所有必要的庫(kù)模塊復(fù)制到最終的可執(zhí)行映像中來(lái)創(chuàng)建靜態(tài)庫(kù)。鏈接器鏈接靜態(tài)庫(kù)作為編譯過(guò)程的最后一步??蓤?zhí)行文件是通過(guò)解析外部引用、將庫(kù)例程與程序代碼相結(jié)合來(lái)創(chuàng)建的。

創(chuàng)建目標(biāo)文件

下面是一個(gè)靜態(tài)庫(kù)的示例,以及鏈接過(guò)程。首先,使用這些函數(shù)簽名創(chuàng)建頭文件mymath.h:

int add(int a, int b);
int sub(int a, int b);
int mult(int a, int b);
int divi(int a, int b);

使用以下函數(shù)定義創(chuàng)建add.c、sub.c和:mult.cdivi.c

// add.c
int add(int a, int b){
return (a+b);
}
//sub.c
int sub(int a, int b){
return (a-b);
}
//mult.c
int mult(int a, int b){
return (a*b);
}
//divi.c
int divi(int a, int b){
return (a/b);
}

現(xiàn)在生成目標(biāo)文件add.o, sub.o, mult.o, divi.o,并使用 GCC:

linuxmi@linuxmi /home/linuxmi/www.linuxmi.com                              
? gcc -c add.c sub.c mult.c divi.c

該-c選項(xiàng)跳過(guò)鏈接步驟并僅創(chuàng)建目標(biāo)文件。

創(chuàng)建一個(gè)名為 的靜態(tài)庫(kù)libmymath.a,然后刪除不再需要的目標(biāo)文件。(請(qǐng)注意,使用比rm命令使用更安全的trash命令 。)

linuxmi@linuxmi /home/linuxmi/www.linuxmi.com                              
? ar rs libmymath.a add.o sub.o mult.o divi.o

$ trash *.o
$ ls
add.c divi.c libmymath.a mult.c mymath.h sub.c

您現(xiàn)在已經(jīng)創(chuàng)建了一個(gè)名為 的簡(jiǎn)單示例數(shù)學(xué)庫(kù)libmymath,您可以在 C 代碼中使用它。當(dāng)然,那里有非常復(fù)雜的 C 庫(kù),這是他們的開(kāi)發(fā)人員用來(lái)生成最終產(chǎn)品的過(guò)程,您和我安裝這些產(chǎn)品以用于 C 代碼。

接下來(lái),在一些自定義代碼中使用您的數(shù)學(xué)庫(kù),然后鏈接它。

創(chuàng)建靜態(tài)鏈接的應(yīng)用程序

假設(shè)你寫(xiě)了一個(gè)數(shù)學(xué)命令。創(chuàng)建一個(gè)名為mathDemo.c的文件并將以下代碼粘貼到其中:

#include <mymath.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x, y;
printf("Enter two numbers\n");
scanf("%d%d",&x,&y);

printf("\n%d + %d = %d", x, y, add(x, y));
printf("\n%d - %d = %d", x, y, sub(x, y));
printf("\n%d * %d = %d", x, y, mult(x, y));
if(y==0){
printf("\nDenominator is zero so can't perform division\n");
exit(0);
}else{
printf("\n%d / %d = %d\n", x, y, divi(x, y));
return 0;
}
}

請(qǐng)注意,第一行是include按名稱(chēng)引用您自己的libmymath庫(kù)的語(yǔ)句。

從mathDemo.c創(chuàng)建一個(gè)名為mathDemo.o的目標(biāo)文件:

linuxmi@linuxmi /home/linuxmi/www.linuxmi.com                              
? gcc -I . -c mathDemo.c

該-I 選項(xiàng)告訴 GCC 搜索其后列出的頭文件。在這種情況下,您指定的是當(dāng)前目錄,由一個(gè)點(diǎn) ( .) 表示。

鏈接mathDemo.o以libmymath.a創(chuàng)建最終的可執(zhí)行文件。有兩種方法可以向 GCC 表達(dá)這一點(diǎn)。

您可以指向文件:

linuxmi@linuxmi /home/linuxmi/www.linuxmi.com                              
? gcc -static -o mathDemo mathDemo.o libmymath.a

或者,您可以指定庫(kù)路徑以及庫(kù)名稱(chēng):

linuxmi@linuxmi /home/linuxmi/www.linuxmi.com                              
? gcc -static -o mathDemo -L . mathDemo.o -lmymath

在后一個(gè)示例中,該-lmymath選項(xiàng)告訴鏈接器將存在的目標(biāo)文件libmymath.a與目標(biāo)文件鏈接mathDemo.o以創(chuàng)建最終的可執(zhí)行文件。該-L選項(xiàng)指示鏈接器在以下參數(shù)中查找?guī)欤?lèi)似于您將使用的-I)。

分析結(jié)果

使用file命令確認(rèn)它是靜態(tài)鏈接的:

linuxmi@linuxmi /home/linuxmi/www.linuxmi.com                              
? file mathDemo

mathDemo: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=c43a2cdedc68087433caf94b67ae079a02bc0bc9, for GNU/Linux 3.2.0, not stripped

使用ldd命令,可以看到可執(zhí)行文件沒(méi)有動(dòng)態(tài)鏈接:

linuxmi@linuxmi /home/linuxmi/www.linuxmi.com                              
? ldd ./mathDemo

 不是動(dòng)態(tài)可執(zhí)行文件

您還可以檢查可執(zhí)行文件mathDemo的大小:

linuxmi@linuxmi /home/linuxmi/www.linuxmi.com                              
? du -h ./mathDemo
984K ./mathDemo

運(yùn)行命令查看它的工作情況:  

linuxmi@linuxmi /home/linuxmi/www.linuxmi.com                              
? ./mathDemo
Enter two numbers
20
5
20 + 5 = 25
20 - 5 = 15
20 * 5 = 100
20 / 5 = 4

何時(shí)使用靜態(tài)鏈接

動(dòng)態(tài)鏈接的可執(zhí)行文件通常比靜態(tài)鏈接的可執(zhí)行文件更受歡迎,因?yàn)閯?dòng)態(tài)鏈接使應(yīng)用程序的組件保持模塊化。如果庫(kù)收到重要的安全更新,它可以很容易地修補(bǔ),因?yàn)樗嬖谟谑褂盟膽?yīng)用程序之外。

當(dāng)您使用靜態(tài)鏈接時(shí),庫(kù)的代碼會(huì)“隱藏”在您創(chuàng)建的可執(zhí)行文件中,這意味著修補(bǔ)它的唯一方法是在每次庫(kù)獲得更新時(shí)重新編譯和重新發(fā)布新的可執(zhí)行文件 - 你有更好的與你的時(shí)間有關(guān)的事情,相信我。

但是,如果庫(kù)的代碼存在于與使用它的可執(zhí)行文件相同的代碼庫(kù)中,或者存在于預(yù)期不會(huì)接收更新的專(zhuān)用嵌入式設(shè)備中,則靜態(tài)鏈接是一個(gè)合理的選擇。

責(zé)任編輯:龐桂玉 來(lái)源: Linux公社
相關(guān)推薦

2022-07-12 13:23:59

靜態(tài)鏈接庫(kù)可執(zhí)行文件C 目標(biāo)文件

2023-03-05 16:36:14

Linux鏈接目標(biāo)文件

2009-09-23 15:37:52

Hibernate 原

2019-12-06 11:18:07

LinuxCPU架構(gòu)

2011-03-11 09:41:17

JavaGC

2009-08-28 12:47:30

C#靜態(tài)方法應(yīng)用

2020-10-16 08:30:00

foreach編程語(yǔ)言C#

2011-08-02 14:15:05

XCode 靜態(tài) 鏈接庫(kù)

2010-06-18 15:49:41

ACPId服務(wù)

2009-06-05 11:01:23

struts mvcMVC工作原理

2009-10-27 14:31:57

linux靜態(tài)路由

2009-08-31 09:41:05

C#反射靜態(tài)方法開(kāi)發(fā)

2018-06-01 09:17:52

區(qū)塊鏈以太坊

2009-12-23 16:28:13

Linux GCC

2023-04-04 12:20:28

靜態(tài)資源配置

2010-12-12 21:58:00

半靜態(tài)語(yǔ)言動(dòng)態(tài)語(yǔ)言靜態(tài)語(yǔ)言

2009-07-09 14:01:22

JVM工作原理

2010-09-26 08:50:11

JVM工作原理

2009-11-09 08:53:21

ASP.NET緩存

2010-06-22 10:28:04

linux at命令
點(diǎn)贊
收藏

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