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

快速掌握 Go 二進(jìn)制文件的靜態(tài)和動(dòng)態(tài)鏈接

開發(fā) 前端
今天我們快速的介紹了 Go 語言中的靜態(tài)和動(dòng)態(tài)鏈接的基本概念,打了個(gè)底。靜態(tài)鏈接會(huì)實(shí)現(xiàn) ALL IN ONE 的效果,確保編譯出來的二進(jìn)制文件能夠在標(biāo)準(zhǔn)的環(huán)境下運(yùn)行。而動(dòng)態(tài)鏈接則相反。

大家好,我是煎魚。

在編寫 Go 應(yīng)用程序時(shí),Go 本身提供了跨平臺(tái)編譯,提供了非常大的便利。但內(nèi)部其實(shí)有許多靜態(tài)和動(dòng)態(tài)鏈接的相關(guān)知識(shí)點(diǎn)。

今天給大家分享這一塊的基本知識(shí)。

如何選擇?Go 團(tuán)隊(duì)的討論

Go 核心團(tuán)隊(duì)在創(chuàng)造這門編程語言時(shí)已經(jīng)做了大量的討論和權(quán)衡。

圖片圖片

“靜態(tài)鏈接有很多優(yōu)點(diǎn)。部署簡(jiǎn)單是其中之一。沒有版本問題是另一個(gè)優(yōu)點(diǎn)(升級(jí)可能永遠(yuǎn)不會(huì)破壞您的 go 二進(jìn)制文件。但動(dòng)態(tài)鏈接或解釋語言則不然,因?yàn)橐蕾囮P(guān)系可能會(huì)中斷)。啟動(dòng)時(shí)間更快也是另一個(gè)優(yōu)點(diǎn)。

不過,動(dòng)態(tài)鏈接也有很好的理由。真實(shí)原因是:因?yàn)?go 作者已經(jīng)研究了靜態(tài)鏈接與動(dòng)態(tài)鏈接的權(quán)衡,并決定靜態(tài)鏈接更適合他們的用例。而且 go 社區(qū)中的大多數(shù)人都同意這一點(diǎn)。”

靜態(tài)和動(dòng)態(tài)鏈接是什么?

靜態(tài)和動(dòng)態(tài)鏈接是兩種不同的程序鏈接方式,一般會(huì)根據(jù)實(shí)際的程序運(yùn)行情況進(jìn)行選擇。

圖片圖片

靜態(tài)鏈接

在編譯時(shí),鏈接器將程序所需的所有庫文件直接復(fù)制到可執(zhí)行文件中,生成一個(gè)完整的可執(zhí)行文件。

一旦生成后,執(zhí)行時(shí)不再依賴外部庫。

  • 優(yōu)點(diǎn):簡(jiǎn)單且不需要額外的庫文件。
  • 缺點(diǎn):可執(zhí)行文件較大,更新庫時(shí)需要重新編譯。

動(dòng)態(tài)鏈接

在程序運(yùn)行時(shí),操作系統(tǒng)根據(jù)需要加載共享庫到內(nèi)存中。

這使得可執(zhí)行文件更小,因?yàn)樗话械膸齑a,但程序執(zhí)行時(shí)依賴于外部庫的存在。

  • 優(yōu)點(diǎn):在于節(jié)省內(nèi)存和便于庫的更新。
  • 缺點(diǎn):可能存在一些版本兼容性問題等。

快速例子

靜態(tài)鏈接

對(duì)于 Go 這一門編程語言而言,靜態(tài)鏈接是他大力宣傳的一個(gè)招牌:只需要編譯一個(gè)二進(jìn)制文件,哪里都可以部署。

示例代碼如下:

package main

import (
 "fmt"
)

func main() {
 fmt.Println("腦子進(jìn)煎魚了!")
}

輸出結(jié)果:

腦子進(jìn)煎魚了!

強(qiáng)制指定 CGO_ENABLED=0 來進(jìn)行編譯:

CGO_ENABLED=0 go build main.go

使用 file 工具查看目標(biāo)文件信息:

$ file greet
greet: Mach-O 64-bit executable arm64

結(jié)合查看 fmt.Println 是否固定地址:

圖片圖片

結(jié)合來看,可以確定 Go 程序本身的依賴是靜態(tài)鏈接的。而編譯出來的二進(jìn)制程序到底有沒有動(dòng)態(tài)鏈接庫,取決于你所編寫的程序。

動(dòng)態(tài)鏈接

Go 應(yīng)用程序在進(jìn)行 go build 的時(shí)候,可以加入 -buildmode 參數(shù)來指定構(gòu)建模式,以此實(shí)現(xiàn)動(dòng)態(tài)鏈接的目的。

以下是可用的 buildmode 選項(xiàng):

  • archive: 將非 main 包構(gòu)建成 .a 文件,main 包將被排除。
  • c-archive: 構(gòu)建 main 包及其依賴的所有包為 C 歸檔文件。
  • c-shared: 構(gòu)建指定的 main 包及其所有依賴為 C 動(dòng)態(tài)庫。
  • shared: 將所有非 main 包整合到一個(gè)動(dòng)態(tài)庫中。
  • exe: 構(gòu)建指定的 main 包及其依賴為可執(zhí)行文件,未命名為 main 的包將被忽略。

默認(rèn)情況下,main 包會(huì)被內(nèi)置到可執(zhí)行文件中,非 main 包則會(huì)被內(nèi)置到 .a 文件中。

這塊我們寫 Web 程序的用的不多,如果是寫 C 庫或者調(diào)第三方語言的動(dòng)態(tài)庫時(shí)用得多。此時(shí)需要在編譯時(shí)指定 CGO_ENABLED=1 才可以。

有興趣的話,CGO 例子可以參考:andreiavrammsd/cgo-examples[1],這里不展開。

總結(jié)

今天我們快速的介紹了 Go 語言中的靜態(tài)和動(dòng)態(tài)鏈接的基本概念,打了個(gè)底。靜態(tài)鏈接會(huì)實(shí)現(xiàn) ALL IN ONE 的效果,確保編譯出來的二進(jìn)制文件能夠在標(biāo)準(zhǔn)的環(huán)境下運(yùn)行。而動(dòng)態(tài)鏈接則相反。

這是 Go 這門編程語言設(shè)計(jì)時(shí)的一個(gè)招牌特性,而我們做 Web 開發(fā)的話,一般都是以靜態(tài)鏈接為主。

如果有涉及到第三方調(diào)用才會(huì)用到動(dòng)態(tài)鏈接等。我見過用 CGO 逐步重構(gòu) C 服務(wù)的,甚至要慎防內(nèi)存泄露。這時(shí)候又是另外一套邏輯、體系了,要進(jìn)一步進(jìn)修!

責(zé)任編輯:武曉燕 來源: 腦子進(jìn)煎魚了
相關(guān)推薦

2020-05-22 18:00:26

Go二進(jìn)制文件編程語言

2022-07-26 13:00:01

安全符號(hào)源代碼

2009-12-16 10:49:42

Ruby操作二進(jìn)制文件

2009-08-12 18:06:53

C#讀取二進(jìn)制文件

2009-02-27 09:37:33

Google二進(jìn)制代碼

2013-04-28 15:37:35

JBoss

2024-02-01 09:04:12

2020-10-21 09:49:31

Ghidra逆向分析

2009-12-10 09:24:50

PHP函數(shù)fwrite

2023-09-18 23:50:25

二進(jìn)制文件裁剪Layout

2015-07-21 11:43:14

CentosRPM

2020-10-19 11:35:47

Ghidra逆向分析G

2025-04-02 11:30:00

MySQL二進(jìn)制部署數(shù)據(jù)庫

2022-01-26 00:02:01

Go二進(jìn)制元信息

2017-04-11 10:48:53

JS二進(jìn)制

2010-10-13 15:45:23

MySQL二進(jìn)制日志

2023-12-26 15:10:00

處理二進(jìn)制文件

2009-11-02 11:27:42

VB.NET二進(jìn)制文件

2018-10-22 14:37:16

二進(jìn)制數(shù)據(jù)存儲(chǔ)

2022-10-31 08:02:42

二進(jìn)制計(jì)算乘法
點(diǎn)贊
收藏

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