亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目次
なぜダイナミック リンクなのか? " >なぜダイナミック リンクなのか?
動態(tài)鏈接的方式" >動態(tài)鏈接的方式
延遲綁定技術(shù)" >延遲綁定技術(shù)
顯式運行時鏈接" >顯式運行時鏈接
總結(jié)" >總結(jié)
ホームページ システムチュートリアル Linux Linuxにおけるダイナミックリンクとスタティックリンクの本來の意味は何でしょうか?

Linuxにおけるダイナミックリンクとスタティックリンクの本來の意味は何でしょうか?

Feb 05, 2024 pm 05:45 PM
linux Linuxチュートリアル Linuxシステム 遅延読み込み Linuxコマンド シェルスクリプト 埋め込みLinux 良い約束 Linux を始める Linux學(xué)習(xí)

古いルールです。最初にいくつか質(zhì)問してください:

  • なぜダイナミックリンクなのか?
  • 動的リンクを行うにはどうすればよいですか?
  • アドレス非依存コード技術(shù)とは何ですか?
  • 遅延結(jié)合技術(shù)とは何ですか?
  • プログラムの実行中に明示的なリンクを行うにはどうすればよいですか?

なぜダイナミック リンクなのか?

動的リンクの出現(xiàn)は、靜的リンクのいくつかの欠點を解決することです:

  1. メモリとディスク容量を節(jié)約します。次の図に示すように、
Linux 動態(tài)鏈接與靜態(tài)鏈接原來是這么回事?

Program1 と Program2 には、それぞれ Program1.o と Program2.o という 2 つのモジュールが含まれており、どちらも Lib.o モジュールを必要とします。靜的リンクの場合、両方のターゲット ファイルが Lib.o モジュールを使用するため、リンクによって同時に出力される実行可能ファイル Program1 と Program2 にコピーが存在します。同時に実行すると、Lib.o には 2 つのコピーがあります。ディスク上とメモリ上にコピーがあり、システム內(nèi)でターゲット ファイルを共有する Lib.o に似た複數(shù)のプログラムが多數(shù)ある場合、多くのスペースが無駄になります。

  1. 靜的リンクはプログラム更新の展開とリリースにとって非常に不親切です

モジュールが 20 個のモジュールに依存している場合、20 個のモジュールの 1 つを更新する必要がある場合、更新が成功する前にすべてのモジュールが検索され、実行可能プログラムに再コンパイルされる必要があります。モジュールが更新されるたびにモジュールの場合、ユーザーは非常に大きなプログラムを再取得する必要があります。プログラムが靜的リンクを使用している場合、ネットワーク経由でプログラムを更新するのは非常に不便です。プログラムのどこかに小さな変更があると、全體がプログラムが再ダウンロードされます。

靜的リンクの欠點を解決するために、動的リンクが導(dǎo)入され、動的リンクのメモリ配分は図のようになります。

Linux 動態(tài)鏈接與靜態(tài)鏈接原來是這么回事?複數(shù)のプログラムが同じ共有オブジェクト ファイルに依存します。この共有オブジェクト ファイルのコピーはディスク上とメモリ上に 1 つだけ存在し、コピーは生成されません。簡単に言うと、靜的リンクとは異なります。プログラムを構(gòu)成するオブジェクト ファイルへのリンクを?qū)g行し、プログラムが実行されるまで待機(jī)し、プログラムが実行されるまでリンク プロセスを延期します。ダイナミック リンク方式により、開発プロセス中の各モジュールの獨立性が高まり、結(jié)合が少なくなるため、さまざまな開発者や開発組織が獨立して開発およびテストすることが容易になります。

動的リンクを?qū)g行するにはどうすればよいですか?

次のコードを見てください:

リーリー

コンパイルと実行のプロセスは次のとおりです:

リーリー

-fPIC および -shared を使用してダイナミック リンク ライブラリを生成し、それを?qū)g行可能プログラムにリンクして通常どおり実行できます。

readelf コマンドを使用して、ダイナミック リンク ライブラリのセグメント情報を表示できます。

リーリー

ダイナミック リンク モジュールのロード アドレスが 0 から始まることがわかります。0 は無効なアドレスです。ロード アドレスはプログラムの実行時に決定され、コンパイル時には不確かです。

プログラムを変更します: リーリー

実行してマップ情報を読み取ります:

~/test$?./test?&
[1]?126
~/test$?func?1
cat?/proc/126/maps
7ff2c59f0000-7ff2c5bd7000?r-xp?00000000?00:00?516391?????????????/lib/x86_64-linux-gnu/libc-2.27.so
7ff2c5bd7000-7ff2c5be0000?---p?001e7000?00:00?516391?????????????/lib/x86_64-linux-gnu/libc-2.27.so
7ff2c5be0000-7ff2c5dd7000?---p?000001f0?00:00?516391?????????????/lib/x86_64-linux-gnu/libc-2.27.so
7ff2c5dd7000-7ff2c5ddb000?r--p?001e7000?00:00?516391?????????????/lib/x86_64-linux-gnu/libc-2.27.so
7ff2c5ddb000-7ff2c5ddd000?rw-p?001eb000?00:00?516391?????????????/lib/x86_64-linux-gnu/libc-2.27.so
7ff2c5ddd000-7ff2c5de1000?rw-p?00000000?00:00?0
7ff2c5df0000-7ff2c5df1000?r-xp?00000000?00:00?189022?????????????/mnt/d/wzq/wzq/util/test/lib.so
7ff2c5df1000-7ff2c5df2000?---p?00001000?00:00?189022?????????????/mnt/d/wzq/wzq/util/test/lib.so
7ff2c5df2000-7ff2c5ff0000?---p?00000002?00:00?189022?????????????/mnt/d/wzq/wzq/util/test/lib.so
7ff2c5ff0000-7ff2c5ff1000?r--p?00000000?00:00?189022?????????????/mnt/d/wzq/wzq/util/test/lib.so
7ff2c5ff1000-7ff2c5ff2000?rw-p?00001000?00:00?189022?????????????/mnt/d/wzq/wzq/util/test/lib.so
7ff2c6000000-7ff2c6026000?r-xp?00000000?00:00?516353?????????????/lib/x86_64-linux-gnu/ld-2.27.so
7ff2c6026000-7ff2c6027000?r-xp?00026000?00:00?516353?????????????/lib/x86_64-linux-gnu/ld-2.27.so
7ff2c6227000-7ff2c6228000?r--p?00027000?00:00?516353?????????????/lib/x86_64-linux-gnu/ld-2.27.so
7ff2c6228000-7ff2c6229000?rw-p?00028000?00:00?516353?????????????/lib/x86_64-linux-gnu/ld-2.27.so
7ff2c6229000-7ff2c622a000?rw-p?00000000?00:00?0
7ff2c62e0000-7ff2c62e3000?rw-p?00000000?00:00?0
7ff2c62f0000-7ff2c62f2000?rw-p?00000000?00:00?0
7ff2c6400000-7ff2c6401000?r-xp?00000000?00:00?189023?????????????/mnt/d/wzq/wzq/util/test/test
7ff2c6600000-7ff2c6601000?r--p?00000000?00:00?189023?????????????/mnt/d/wzq/wzq/util/test/test
7ff2c6601000-7ff2c6602000?rw-p?00001000?00:00?189023?????????????/mnt/d/wzq/wzq/util/test/test
7fffee96f000-7fffee990000?rw-p?00000000?00:00?0?????????????????[heap]
7ffff6417000-7ffff6c17000?rw-p?00000000?00:00?0?????????????????[stack]
7ffff729d000-7ffff729e000?r-xp?00000000?00:00?0?????????????????[vdso]

可以看到,整個進(jìn)程虛擬地址空間中,多出了幾個文件的映射,lib.so和test一樣,它們都是被操作系統(tǒng)用同樣的方法映射到進(jìn)程的虛擬地址空間,只是它們占據(jù)的虛擬地址和長度不同.

從maps里可以看見里面還有l(wèi)ibc-2.27.so,這是C語言運行庫,還有一個ld-2.27.so,這是Linux下的動態(tài)鏈接器,動態(tài)鏈接器和普通共享對象一樣被映射到進(jìn)程的地址空間,在系統(tǒng)開始運行test前,會先把控制權(quán)交給動態(tài)鏈接器,動態(tài)鏈接器完成所有的動態(tài)鏈接工作后會把控制權(quán)交給test,然后執(zhí)行test程序。

當(dāng)鏈接器將Program.o鏈接成可執(zhí)行文件時,這時候鏈接器必須確定目標(biāo)文件中所引用的func函數(shù)的性質(zhì),如果是一個定義于其它靜態(tài)目標(biāo)文件中的函數(shù),那么鏈接器將會按照靜態(tài)鏈接的規(guī)則,將Program.o的func函數(shù)地址進(jìn)行重定位,如果func是一個定義在某個動態(tài)鏈接共享對象中的函數(shù),那么鏈接器將會將這個符號的引用標(biāo)記為一個動態(tài)鏈接的符號,不對它進(jìn)行地址重定位,將這個過程留在裝載時再進(jìn)行。

動態(tài)鏈接的方式

動態(tài)鏈接有兩種方式:裝載時重定位和地址無關(guān)代碼技術(shù)。

裝載時重定位:

在鏈接時對所有絕對地址的引用不作重定位,而把這一步推遲到裝載時完成,也叫基址重置,每個指令和數(shù)據(jù)相當(dāng)于模塊裝載地址是固定的,系統(tǒng)會分配足夠大的空間給裝載模塊,當(dāng)裝載地址確定后,那指令和數(shù)據(jù)地址自然也就確定了。

然而動態(tài)鏈接模塊被裝載映射到虛擬空間,指令被重定位后對于每個進(jìn)程來講是不同的,沒有辦法做到同一份指令被多個進(jìn)程共享,所以指令對不同的進(jìn)程來說有不同的副本,還是空間浪費,怎么解決這個問題?使用fPIC方法。

地址無關(guān)代碼:

指令部分無法在多個進(jìn)程之間共享,不能節(jié)省內(nèi)存,所以引入了地址無關(guān)代碼的技術(shù)。我們平時編程過程中可能都見過-fPIC的編譯選項,這個就代表使用了地址無關(guān)代碼技術(shù)來實現(xiàn)真正的動態(tài)鏈接。

基本思想就是使用GOT(全局偏移表),這是一個指向變量或函數(shù)地址的指針數(shù)組,當(dāng)指令要訪問變量或者調(diào)用函數(shù)時,會去GOT中找到相應(yīng)的地址進(jìn)行間接跳轉(zhuǎn)訪問,每個變量或函數(shù)都對應(yīng)一個地址,鏈接器在裝載模塊的時候會查找每個變量和函數(shù)的地址,然后填充GOT中的各個項,確保每個指針指向的地址正確。GOT放在數(shù)據(jù)段,所以它可以在模塊裝載時被修改,并且每個進(jìn)程都可以有獨立的副本,相互不受影響。

tips

?

-fpic和-fPIC的區(qū)別:它們都是地址無關(guān)代碼技術(shù),-fpic產(chǎn)生的代碼相對較小較快,但是在某些平臺會有些限制,所以大多數(shù)情況下都是用-fPIC來產(chǎn)生地址無關(guān)代碼。

?

-fPIC和-fPIE的區(qū)別:一個作用于共享對象,一個作用于可執(zhí)行文件,一個以地址無關(guān)方式編譯的可執(zhí)行文件被稱作地址無關(guān)可執(zhí)行文件。

?

-fpie和-fPIE的區(qū)別:類似于-fpic和-fPIC的區(qū)別

延遲綁定技術(shù)

在程序剛啟動時動態(tài)鏈接器會尋找并裝載所需要的共享對象,然后進(jìn)行符號地址尋址重定位等工作,這些工作會減慢程序的啟動速度,如果解決?

使用PLT延遲綁定技術(shù),這里會單獨有一個叫.PLT的段,ELF將 GOT拆分成兩個表.GOT和.GOT.PLT,其中.GOT用來保存全局變量的引用地址,.GOT.PLT用來保存外部函數(shù)的地址,每個外部函數(shù)在PLT中都有一個對應(yīng)項,在初始化時不會綁定,而是在函數(shù)第一次被用到時才進(jìn)行綁定,將函數(shù)真實地址與對應(yīng)表項進(jìn)行綁定,之后就可以進(jìn)行間接跳轉(zhuǎn)。

顯式運行時鏈接

支持動態(tài)鏈接的系統(tǒng)往往都支持顯式運行時鏈接,也叫運行時加載,讓程序自己在運行時控制加載的模塊,在需要時加載需要的模塊,在不需要時將其卸載。這種運行時加載方式使得程序的模塊組織變得很靈活,可以用來實現(xiàn)一些諸如插件、驅(qū)動等功能。

通過這四個API可以進(jìn)行顯式運行時鏈接:

dlopen():打開動態(tài)鏈接庫
dlsym():查找符號
dlerror():錯誤處理
dlclose():關(guān)閉動態(tài)鏈接庫

參考這段使用代碼:

#include?
#include?

int?main()?{
???
???void?*handle;
???void?(*f)(int);
???char?*error;

???handle?=?dlopen("./lib.so",?RTLD_NOW);
???if?(handle?==?NULL)?{
???????printf("handle?null?\n");
???????return?-1;
??}
???f?=?dlsym(handle,?"func");
???do?{
???????if?((error?=?dlerror())?!=?NULL)?{
???????????printf("error\n");
???????????break;
??????}
???????f(100);
??}?while?(0);
???dlclose(handle);

???return?0;
}

編譯運行:

$?gcc?-o?test?program.c?-ldl
$?./test
func?100

總結(jié)

為什么要進(jìn)行動態(tài)鏈接?為了解決靜態(tài)鏈接浪費空間和更新困難的缺點。

動的リンクするにはどうすればよいですか? ロード時の再配置とアドレスに依存しないコード テクノロジ。

アドレス非依存コード技術(shù)の原則? GOTセグメントを介した間接ジャンプを?qū)g現(xiàn)します。

遅延読み込みテクノロジの原則? 外部関數(shù)シンボルの遅延バインディングと PLT セグメントを介した間接ジャンプを?qū)g裝します。

明示的なランタイム リンクを行うにはどうすればよいですか? ヘッダー ファイル內(nèi)の 4 つの関數(shù)を使用すると、コードは上記のようになります。

以上がLinuxにおけるダイナミックリンクとスタティックリンクの本來の意味は何でしょうか?の詳細(xì)內(nèi)容です。詳細(xì)については、PHP 中國語 Web サイトの他の関連記事を參照してください。

このウェブサイトの聲明
この記事の內(nèi)容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰屬します。このサイトは、それに相當(dāng)する法的責(zé)任を負(fù)いません。盜作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡(luò)ください。

ホットAIツール

Undress AI Tool

Undress AI Tool

脫衣畫像を無料で

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード寫真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

寫真から衣服を削除するオンライン AI ツール。

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中國語版

SublimeText3 中國語版

中國語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統(tǒng)合開発環(huán)境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Windows(デュアルブート)と一緒にLinuxをインストールする方法は? Windows(デュアルブート)と一緒にLinuxをインストールする方法は? Jun 18, 2025 am 12:19 AM

LinuxとWindowsにデュアルシステムをインストールするための鍵は、パーティションの設(shè)定とブート設(shè)定です。 1.準(zhǔn)備には、データのバックアップと既存のパーティションを圧縮してスペースを作成することが含まれます。 2. VentoyまたはRufusを使用してLinux Boot USBディスクを作成します。Ubuntuをお勧めします。 3.「他のシステムと共存」を選択するか、インストール中に手動でパーティションをかけます( /少なくとも20GB、 /家の殘りスペース、オプションを交換)。 4.ハードウェアの問題を避けるために、サードパーティのドライバーのインストールを確認(rèn)します。 5.インストール後にGrub Bootメニューを入力しない場合は、ブート修理を使用してブートを修復(fù)するか、BIOSスタートアップシーケンスを調(diào)整できます。手順が明確で、操作が適切に行われている限り、プロセス全體が複雑ではありません。

Epel(Enterprise Linux用の追加パッケージ)リポジトリを有効にする方法は? Epel(Enterprise Linux用の追加パッケージ)リポジトリを有効にする方法は? Jun 17, 2025 am 09:15 AM

Epelリポジトリを有効にするための鍵は、システムバージョンに応じて正しいインストール方法を選択することです。まず、システムの種類とバージョンを確認(rèn)し、コマンドcat/etc/osリリースを使用して情報を取得します。第二に、centos/rockylinuxでdnfinstallepelリリースを介してepelを有効にし、8および9バージョンのコマンドは同じです。第三に、.Repoファイルの対応するバージョンを手動でダウンロードし、RHELにインストールする必要があります。第4に、問題に遭遇したときにGPGキーを再輸入できます。古いバージョンはサポートされていない可能性があることに注意してください。また、Epel-Nextがテストパッケージを取得できるようにすることも検討することもできます。上記の手順を完了した後、DNFrepolistを使用して、Epelリポジトリが正常に追加されていることを確認(rèn)します。

初心者向けにLinuxディストリビューションを選択する方法は? 初心者向けにLinuxディストリビューションを選択する方法は? Jun 19, 2025 am 12:09 AM

初心者のユーザーは、Linuxディストリビューションを選択する際に、まず使用要件を明確にする必要があります。 1.毎日使用するには、ubuntuまたはlinuxmintを選択します。プログラミングと開発は、マンジャロまたはフェドー??ラに適しています。古いデバイスにはLubuntuおよびその他の軽量システムを使用します。根本的な原則を?qū)Wぶために、CentosstreamまたはDebianをお勧めします。 2。UbuntultsまたはDebianには安定性が好ましい。 ArchまたはManjaroを選択して、新しい機(jī)能を追求できます。 3。コミュニティのサポートに関しては、UbuntuとLinuxmintにはリソースが豊富であり、アーチ文書は技術(shù)的に指向されています。 4.インストールの難易度の観點から、UbuntuとLinuxmintは比較的単純であり、Archは基本的なニーズを持つ人に適しています。最初に試してから決定することをお勧めします。

Linuxに新しいディスクを追加する方法 Linuxに新しいディスクを追加する方法 Jun 27, 2025 am 12:15 AM

Linuxシステムに新しいハードディスクを追加する手順は次のとおりです。1。ハードディスクが認(rèn)識されていることを確認(rèn)し、LSBLKまたはFDISK-Lを使用して確認(rèn)します。 2。FDISK/DEV/SDBなどのFDISKまたは別れのパーティションを使用して作成および保存します。 3。mkfs.ext4/dev/sdb1などのファイルシステムにパーティションをフォーマットします。 4。マウント/dev/sdb1/mnt/dataなどの一時マウントにマウントコマンドを使用します。 5. /etc /fstabを変更してコンピューターで自動マウントを?qū)g現(xiàn)し、最初にマウントをテストして、正しさを確保します。ハードウェア接続の問題を避けるために、操作前にデータセキュリティを確認(rèn)してください。

Linuxのシステムログはどこにありますか? Linuxのシステムログはどこにありますか? Jun 24, 2025 am 12:15 AM

Linuxシステムのログは、通常、 /var /logディレクトリに保存されます。これには、syslogやメッセージ(レコードシステムログ)、auth.log(レコード認(rèn)証イベント)、kern.log(レコードカーネルメッセージ)、dpkg.logまたはyum.log(レコードパッケージ操作)、boot.log(record startup startup operations)など、さまざまなキーログファイルが含まれています。ログコンテンツは、CAT、Tail-F、またはJournalCtlコマンドを介して表示できます。アプリケーションログは、多くの場合、Apacheのapache2やHTTPDディレクトリ、MySQLログファイルなど、 /var /logの下のサブディレクトリにあります。同時に、ログの権限は通常sが必要であることに注意する必要があります

Windows Google Chromeにファイルをアップロードできなかったことを修正しました Windows Google Chromeにファイルをアップロードできなかったことを修正しました Jul 08, 2025 pm 02:33 PM

Google Chromeにファイルをアップロードするのに問題がありますか?これは迷惑かもしれませんよね?電子メールにドキュメントを添付したり、ソーシャルメディアで畫像を共有したり、仕事や學(xué)校の重要なファイルを送信したりするかどうかにかかわらず、スムーズなファイルのアップロードプロセスが重要です。したがって、Windows PCのChromeでファイルのアップロードが引き続き失敗している場合、イライラする可能性があります。お気に入りのブラウザを放棄する準(zhǔn)備ができていない場合は、Windows Google Chrome 1にファイルをアップロードできない修正のヒントをいくつか紹介します。高度なトラブルシューティングのヒントについて學(xué)ぶ前に、ユニバーサル修理から始めて、以下に説明する基本的なソリューションを試すのが最善です。インターネット接続の問題のトラブルシューティング:インターネット接続

Sudoコマンドとは何ですか、いつ使用すればよいですか? Sudoコマンドとは何ですか、いつ使用すればよいですか? Jul 02, 2025 am 12:20 AM

Sudoは「SollideSerdo」または「Superuserdo」の略で、ユーザーが他のユーザー(通常はroot)の許可を使用してコマンドを?qū)g行できるようにします。そのコアの使用には、次のものが含まれます。1。ソフトウェアのインストールやシステムファイルの編集など、システムレベルの操作を?qū)g行します。 2。保護(hù)されたディレクトリまたはログへのアクセス。 3。nginxの再起動などのサービスを管理します。 4. /etc /hostsなどのグローバル設(shè)定を変更します。使用すると、システムは /etc /sudoers構(gòu)成をチェックし、ユーザーパスワードを確認(rèn)し、rootとして継続的にログインする代わりに一時的なアクセス許可を提供し、セキュリティを確保します。ベストプラクティスには、必要な場合にのみ、ネットワークコマンドの盲目的に実行され、visudoを使用したSudoersファイルの編集、継続的な操作を検討してください。

Linuxでグループを管理する方法 Linuxでグループを管理する方法 Jul 06, 2025 am 12:02 AM

Linuxユーザーグループを管理するには、表示、作成、削除、変更、およびユーザー屬性の調(diào)整の操作をマスターする必要があります。ユーザーグループ情報を表示するには、cat/etc/groupまたはgetentgroupを使用して、グループ[username]またはid [username]を使用して、ユーザーが屬するグループを表示できます。 GroupAddを使用してGroupを作成し、GroupDelを使用してGIDを指定します。 GroupDelを使用して、空のグループを削除します。 USERMOD-AGを使用してユーザーをグループに追加し、USERMOD-Gを使用してメイングループを変更します。 USERMOD-Gを使用して、 /etc /groupを編集するか、VIGRコマンドを使用してグループからユーザーを削除します。 GroupMod-N(名前を変更)またはGroupMod-G(GIDの変更)を使用してグループプロパティを変更し、関連するファイルの許可を更新することを忘れないでください。

See all articles