[Linux] 基本 IO --- ソフト リンクとハード リンク、ACM 時間、動的ライブラリと静的ライブラリの作成、動的リンクと静的リンク、動的ライブラリと静的ライブラリの読み込み原則...

私は粘り強さで幼稚さとわがままをすべて燃やし、荒野はゆっくりと理性的な無関心と冷静さを増していきました。

ここに画像の説明を挿入

記事ディレクトリ



1. ソフトリンクとハードリンク

Linuxファイルタイプ 説明する
b ブロック デバイス ファイルは通常、ハードディスクやフロッピー ディスクなどのストレージ デバイスを指します。
c キャラクター デバイスは、キーボード、マウス、プリンタ、tty 端末などのシリアル ポート インターフェイス デバイスです。
d Windows フォルダーに似たディレクトリ ファイル。
Windows のショートカットに似た、ファイルのリンク。
s ソケット ファイル (ソケット)。主に、特にネットワーク上の通信に使用されます。
p パイプライン ファイル (パイプ)。主にプロセス間通信に使用されます。
- ファイルはプレーンテキストファイル(ASCII)とバイナリファイル(バイナリ)に分けられます。

1. ソフトリンクとハードリンクの違い (独立した i ノードを持つかどうか)

1. 以下は、それぞれソフトリンクとハードリンクの結果です。

[wyn@VM-8-2-centos lesson21]$ ln -s myfile.txt soft_file.link ---软链接

ここに画像の説明を挿入

[wyn@VM-8-2-centos lesson21]$ ln myfile.txt hard_file.link ---硬链接

ここに画像の説明を挿入
ここに画像の説明を挿入
2.
ソフト リンク ファイル Soft_file.link には独自の独立した i ノードがあり、独立したファイルとして扱うことができます
ハード リンク ファイルには、独自の独立した i ノードがありません。myfile.txt の内容が変更されても、hard_file.link も一緒に変更されます。したがって、ハード リンクが確立されても、実際には新しいファイルはまったく作成されません。独立した i ノードがハード リンクに割り当てられます

3.
ハード リンクは新しいファイルを作成しないため、ハード リンクは独自の属性セットとデータ セットを持ってはならず、他のファイルの i ノードとデータ ブロックを使用する必要があります。そのため、ハード リンクの本質は、ファイルを次の場所に追加することです。指定されたパス 名前と inode の間のマッピング関係。inode は複数のファイルによってポイントされます

ここに画像の説明を挿入

4.
i ノード 791188 を指すファイルが 2 つあるため、791188 によって表示される参照カウント (ハード リンクの数とも呼ばれる) は 2 になります。

ここに画像の説明を挿入

ここに画像の説明を挿入

5.
myfile.txt ファイルを削除すると、hard_file.link ファイルのハード リンクの数は自然に 1 になるため、ファイルのハード リンクの数が 0 になると、myfile.txt などのファイルが実際に削除されます。ハードリンクの数が 0 になりました

ここに画像の説明を挿入

2. ソフトリンクとハードリンクの役割

2.1 ソフトリンクの役割(ショートカットの作成)

1.
ソフト リンクのターゲット ファイル myfile.txt を削除した後、ソフト リンクの i ノードはまだ存在するため、実際にはまだ存在しますが、cat がソフト リンク ファイルを出力すると、ファイルが存在しないことが表示されます。つまり、ソフト リンクの Soft_file.link は、ソース ファイルの i ノードが実際にはまだ存在するため、ターゲット ファイルを識別するためにターゲット ファイルの i ノードを使用しません。ソフト リンクはソース ファイル名を使用してソース ファイルを識別していることがわかります

2.
ソフト リンクのデータ ブロックは、それが指すターゲット ファイルのパスを保存するため、ソース ファイルが削除されると、ターゲット ファイルが見つからないため、ソフト リンクは直ちに無効になります。

ここに画像の説明を挿入

3.
ソフト リンクを削除してもソース ファイルには影響しないため、ソフト リンクは Windows のショートカットに相当します。
Edge 属性にはターゲットがあり、これは実際にはソフト リンクで指定されているターゲット ファイルに相当します。ショートカットをダブルクリックして Microsoft Edge を開くことができるのは、ターゲット ファイルが実際には Microsoft の実行可能プログラムであるためです。エッジ
プログラムを実行するたびに、プログラムがダウンロードされているディスクの特定のパスを見つけて、実行可能プログラムをダブルクリックして実行する必要がある場合、すべてのユーザーも混乱する可能性があります。使用するのは困難です。それはあまりにも気持ち悪いので、 Linux のソフトリンクによく似たショートカットのようなものが存在します

[wyn@VM-8-2-centos lesson21]$ unlink soft_file.link ---删除软链接文件

ここに画像の説明を挿入

ここに画像の説明を挿入

4.
以下の図は、ソフト リンクの機能を示しています。これは、指定したディレクトリの深いディレクトリにある実行可能プログラムに対してソフト リンクを確立し、指定したディレクトリ内の実行可能プログラムをすぐに実行できるようにするものです。

ここに画像の説明を挿入

2.2 ハードリンクの役割(重要なファイルの誤削除防止、高速検索、パス(.と..)の切り替え)

1.
表面上、ハード リンクは、ソース ファイルのクローンと同じように、ソース ファイルの名前を変更しているように見えますが、ハード リンクの実際の機能は、ファイルに複数の有効なパス名を持たせることです。重要なファイルへのハードリンクを確立して、「誤って削除」機能を防止できます。
myfile.txt が非常に重要なファイルであると仮定して、myfile.txt へのハード リンクを確立して、hard_file.txt ファイルを形成します。そのため、たとえ誤って myfile.txt ファイルを削除したとしても、データは保存されるので心配しないでください。 Hard_file.txt と myfile .txt はまったく同じであり、重要なファイルのデータ バックアップを作成することと同じです。

ここに画像の説明を挿入

2.
file.txt ファイルは、自身の i ノード自体を指すだけなので、そのハード リンク番号は 1 です。空のディレクトリ ファイルは、それ自体の i ノードを指すだけでなく、ディレクトリの下にある隠しファイルも指します。また、その i ノードも指します。空の i ノードを指すファイルが 2 つあるため、ハード リンクの数は 2 です。空のディレクトリに別のディレクトリを作成すると、ディレクトリ内の隠しファイルも空の i ノードを指しているため、空のディレクトリの
ハード リンクの数は 3 になります。
空のディレクトリ内の dir ディレクトリ ファイル . . は、実際には空のディレクトリ ファイルのハード リンクに相当します。

ここに画像の説明を挿入
ここに画像の説明を挿入

3.
補足知識: ディレクトリ ファイルのサイズは 4096 バイトの倍数で、最小値は 4096 です。4096 は IO ブロックであり、ディスクの読み取りと書き込みの最小単位は 8 セクターであり、サイズはちょうど 4096 バイトです。オペレーティング システムは、ユーザーがディレクトリ ファイルの下でファイルの読み取りと書き込みを行うことを認識しているため、IO ブロック サイズのスペースを直接開きます

以下の記事では、単位に関していくつかの間違いがあるため、弁証法的に見る必要があります。
Linux ではディレクトリのサイズが常に 4096 になるのはなぜですか

4.
以下からわかるように、Linux では一般ユーザーがディレクトリへのハード リンクを作成することはできませんが、Linux 自体はディレクトリへのハード リンク (隠しファイル) を作成できます。ランプを点灯することは禁止されています。

Linux ではディレクトリをハードリンクできないのはなぜですか? (ZhihuブロガーZuiwo戦場ブロガーの記事から転載、説明は非常に非常に詳細です)

通常の状況ではディレクトリをハードリンクできないのはなぜですか (ブロガー Kproxy の記事から転載)

ここに画像の説明を挿入
5.ただし、ソフト リンク ディレクトリは許可されています。ソフト リンク ディレクトリをキャンセルしたい場合は、unlink を使用できますが、ソフト リンク ファイルはファイルではない
ため、ファイルの末尾に / を追加できないことに注意してください。ディレクトリではなくファイルです

ここに画像の説明を挿入
ここに画像の説明を挿入

よく書かれた記事を共有すると、興味のあるパートナーがそれを読むことができます。
Linux のソフト リンクとハード リンク (ブロガー Heropoo のバックエンド シージ ライオンに関する記事から転載)

2 番目に、stat コマンドでの acm 時間

ここに画像の説明を挿入
1.
Access はファイルにアクセスした時刻、
Change はファイルの属性が変更された時刻、
Modify はファイルの内容が変更された時刻を指します。

2.
ファイルの内容を変更すると、ファイルのプロパティのファイル サイズもそれに応じて変更されるため、ファイルの内容を変更した後、変更時間とともに変更も変更されることがよくあります。

3.
初期の Linux オペレーティング システムでは、ファイルにアクセスすると、ファイルのアクセス時間はすぐに変更されましたが、その後、ファイル操作における属性と内容の変更率がそれよりもはるかに大きいことが判明しました。ディスクは周辺機器であるため、ファイル アクセス時間を毎回更新する必要がある場合、頻繁な IO データがオペレーティング システムの効率に影響を及ぼします。
そこで Linux は、アクセス数が一定数に達するとファイルのアクセス時間を一律に更新するなど、当初の戦略を変更し、アクセス時間はリアルタイムに更新されません

3. 動的ライブラリと静的ライブラリの違い(リンク段階、リンク結果、リンク方法の違い)

1.
静的ライブラリには .a という接尾辞が付けられ、プログラムはコンパイルおよびリンクの段階でライブラリのコードを実行可能ファイルにリンクします。プログラムが実行中にメモリにロードされてプロセスになると、静的ライブラリは必要なくなります。
ダイナミック ライブラリには .so という接尾辞が付けられます。プログラムがメモリにロードされてプロセスになると、ダイナミック ライブラリのコードがリンクされます。ダイナミック ライブラリを必要とするメモリ内に複数のプロセスがある場合、複数のプロセスが共有します。ダイナミック ライブラリを使用したコード。

2.
ダイナミック リンクを使用する実行可能ファイルには、ライブラリ ファイル内の外部関数のマシン コード全体ではなく、使用する関数のエントリ アドレスのテーブルのみが含まれます。

3.
実行ファイルがメモリ上にロードされプロセスとなった後、オペレーティングシステムにより外部関数のマシンコードがディスク上のライブラリファイルからメモリ上にコピーされます(ダイナミックリンクと呼ばれます)。

4.
動的ライブラリは複数のプロセス間で共有できるため、動的にリンクされた実行可能ファイルは小さくなり、ディスク領域が節約されます。オペレーティング システムで採用されている仮想メモリ メカニズムにより、物理メモリ内の動的ライブラリを複数のプロセスで共有できるため、メモリ スペースが節約されます。

4. 図書館の性質は何ですか? (.o ファイルのコレクション)

いくつかの簡単なコードを以下に示します。これは、ライブラリとは何か、ライブラリが何を行うのかを理解するのに役立ちます。
ここに画像の説明を挿入

ここに画像の説明を挿入
1.
実行可能プログラムを生成する 2 つの方法は実際には同じです。1つはコンパイルとリンクのプロセスを統合する方法、もう 1 つはコンパイルとリンクのプロセスを分離する方法です。まず、各ソース ファイルをコンパイルしてリロケータブルなターゲット バイナリ ファイルを生成し、次に、複数の .o ファイルがリンクされます。つまり、シンボル テーブルがマージされ、リンク方法は動的リンクと静的リンクに細分化できます。

1.gcc -o mymath main.c my_sub.c my_add.c

2.gcc -c main.c 
gcc -c my_sub.c
gcc -c my_add.c
gcc -o mymath main.o my_sub.o my_add.o

2.
ソース コードを相手に渡したくない場合は、.o リロケータブル ターゲット バイナリ ファイルと .h ヘッダ ファイルを相手に提供し、相手に直接リンク作業を実行させることができます。この方法では、実行可能プログラムを生成することもできます。
左側はライブラリを使用する人に相当し、右側はライブラリを作成した人に相当します。
.o(メソッドの実装)と.h(どんなメソッドがあるか)の集合体を相手に提供するというのがライブラリの考え方です。

ここに画像の説明を挿入

3.
コンパイルするソース ファイルが多すぎる場合は、使いやすくするためにすべての .o ファイルを 1 つのパッケージにパッケージ化することができ、多数の .o ファイルを含むパッケージは実際にはライブラリ ファイルです。パッケージ化方法は動的ライブラリと静的ライブラリに分けられますが、ライブラリの本質は .o ファイルの集合です

5. 静的ライブラリと静的リンク (ar コマンド、.o ファイルをアーカイブ)

1. 静的ライブラリを作成します (.h ファイルと .o ファイルをパッケージ化および圧縮して、ヘッダー ファイルとライブラリ ファイルのコレクションを形成します)。

ここに画像の説明を挿入
tarコマンド、パック、圧縮、解凍の詳しい説明
1.
ar コマンドは実際には archive という単語の最初の 2 文字であり、静的ライブラリはアーカイブ ファイルです。
rc は replace と create の略で、パッケージ化されたファイルが存在しない場合はファイルが作成され、存在する場合はアーカイブ ファイルに置き換えられます。
生成された libmymath.a ファイルはアーカイブになりました。

ここに画像の説明を挿入

  1 libmymath.a:my_add.o my_sub.o
  2     ar -rc $@ $^    ---生成静态库libmymath.a
  3 my_add.o:my_add.c
  4     gcc -c my_add.c
  5 my_sub.o:my_sub.c
  6     gcc -c my_sub.c
  7 
  8 .PHONY:clean
  9 clean:
 10     rm -f *.o libmymath.a      

ここに画像の説明を挿入

2.
libmymath.a (自分で作成したライブラリ ファイル) だけでは十分ではありません。C 言語ではライブラリ ファイル libc.a とヘッダ ファイル stdio.h がユーザーに提供されるため、ヘッダ ファイルがまだ不足しています。
ライブラリを相手に渡すということは、実際には、ライブラリ ファイル (.a/.so) とそれに対応するヘッダー ファイルの両方を相手に渡すことになります。

[wyn@VM-8-2-centos lesson22]$ ls /usr/include/stdio.h
/usr/include/stdio.h
[wyn@VM-8-2-centos lesson22]$ ls /lib64/libc.a
/lib64/libc.a

3.
make Output を実行すると、mylib という名前のライブラリが生成され、ライブラリファイルとヘッダファイルが含まれており、mylib は相手が使用するライブラリファイルとして使用できます。
ライブラリ ファイルのサイズが大きい場合は、圧縮パッケージの形式でユーザーに配信することもできます。

  1 libmymath.a:my_add.o my_sub.o
  2     ar -rc $@ $^    ---生成静态库libmymath.a
  3 my_add.o:my_add.c
  4     gcc -c my_add.c
  5 my_sub.o:my_sub.c
  6     gcc -c my_sub.c
  7 
  8 .PHONY:output
  9 output:
 10     mkdir -p mylib/include 
 11     mkdir -p mylib/lib
 12     cp -f *.a mylib/lib 
 13     cp -f *.h mylib/include                                                                                                           
 14 .PHONY:clean
 15 clean:
 16     rm -f *.o libmymath.a

ここに画像の説明を挿入

mylib ライブラリを mylib.tgz 圧縮パッケージに圧縮し、ライブラリを納品する際に、この圧縮パッケージを相手に渡すことができます。

[wyn@VM-8-2-centos lesson22]$ tar -czvf mylib.tgz mylib

ここに画像の説明を挿入

複数のファイルを削除する場合、効率的に削除するためにワイルドカード * を使用できます。

ここに画像の説明を挿入

左側のライブラリを使用する人は、圧縮パッケージを解凍すると、ライブラリ mylib を入手できます。

ここに画像の説明を挿入

4.
ライブラリを使用する人がライブラリをインストールしたい場合は、対応するファイルをシステム ディレクトリにコピーするだけで済みますので、インストールの本質はコピーです。

[wyn@VM-8-2-centos test]$ cp mylib/include/*.h /usr/include/
[wyn@VM-8-2-centos test]$ cp mylib/lib/libmymath.a /lib64/

2. ユーザーがライブラリを入手した後、コンパイルおよびリンク時に発生する問題

2.1 gcc がヘッダー ファイルを見つけられない

1.
ユーザーが gcc を使用して直接コンパイルおよびリンクすると、ヘッダー ファイルが見つからないことを示すエラーが発生します。
gcc コンパイラーがヘッダー ファイルを検索する場合、2 つの検索方法があります。1つは現在のパス (ソース コードと同じレベルのパス) で検索する方法、もう 1 つはシステムによって指定されたデフォルトのパスで検索する方法です。実際には、mylib ライブラリ内のヘッダー ファイルへの現在のパスの下でそれを見つけることができません。

ここに画像の説明を挿入
2.
したがって、-I オプションを使用して gcc ヘッダー ファイルの検索パスを指定する必要があります。

[wyn@VM-8-2-centos test]$ gcc -o mymath main.c -I ./mylib/include/

2.2 リンク エラー: 関数への未定義の参照 (ライブラリ ファイルが見つからない、ライブラリ検索パス)

1.
命令実行後にリンクエラーが発生する。つまり、前処理、コンパイル、アセンブルの段階では問題がない。
ライブラリ ファイルがシステム パス (/usr/lib64 または /usr/lib パス) にある場合、リンカは対応するライブラリ ファイルを確実に見つけることができますが、リンカは現在のパスでライブラリ ファイルを見つけることができません。

ここに画像の説明を挿入
ここに画像の説明を挿入

2.
したがって、-L オプションを使用してリンカーの検索パスを指定する必要があります。ただし、それに加えて、ライブラリ名を指定する必要があります。
サードパーティのライブラリをリンクする場合は、ライブラリの名前を明示的に指定する必要があるためです

[wyn@VM-8-2-centos test]$ gcc -o mymath main.c -I ./mylib/include/ -L ./mylib/lib/

ライブラリ ファイルのパスを指定するだけでも、システムはリンク エラーを報告します。
ここに画像の説明を挿入

3.
ヘッダー ファイルではヘッダー ファイルの名前を指定する必要はありません。ヘッダー ファイルのパスだけが必要です。これは、ソース コード main.c がコンパイラーにどのヘッダー ファイルをインクルードするかを指示し、gcc がそこに移動するためです。特定のヘッダー ドキュメントを見つけるには、指定されたパスを使用します。
ただし、どのライブラリ ファイルをリンクするかをリンカに指示する人はいないため、ライブラリ ファイルのパスと名前を指定する必要があります。

4.
ただし、以前にコードを書いたときは、ライブラリの名前を指定しませんでした。そのときはサードパーティのライブラリを使用しなかったためです。C または C++ 言語によって提供される標準ライブラリ、またはオペレーティング システムのインターフェイスによって提供されるシステム レベルなので、gcc または g++ は、コードがデフォルトでどのライブラリ ファイルをリンクする必要があるかを決定できますが、今日リンクするライブラリは標準ライブラリではなく、サードパーティ ライブラリです。

ファーストパーティ ライブラリ: システムの
セカンドパーティ ライブラリ: 独自の
サードパーティ ライブラリ: 他人によって作成されたライブラリ

5.
-l オプションを使用してライブラリ名を指定する場合、ライブラリ ファイルの接頭辞 lib と接尾辞 .a または .so を削除する必要があり、中間の残りの部分がライブラリ ファイルの名前になります。

ここに画像の説明を挿入
オプションとその後ろのコンテンツの間には、スペースがあってもなくても問題ありません。スペースなしの自動入力機能は失われますが、スペースなしの方がコンパクトに表示されます。

[wyn@VM-8-2-centos test]$ gcc -o mymath main.c -I./mylib/include/ -L./mylib/lib/ -lmymath

プレフィックスとサフィックスを削除すると、ライブラリ mylib は通常どおり使用できるようになります。
ここに画像の説明を挿入

2.3 特定のリンク方法は何に依存しますか? (提供されたライブラリとコンパイルされたオプションに応じて)

1.
ただし、ldd を使用して共有ライブラリとファイル製品をリストし、mymath ファイルの特定の情報を確認すると、多くのトリックが見つかります。
Gcc はデフォルトで動的にリンクされますが、動的ライブラリを提供せず、gcc 静的ライブラリのみを提供するとどうなるでしょうか。また、実行可能プログラムの形成は 1 つのライブラリのみに依存しない可能性があることがわかっているため、100 個のライブラリ、70 個の静的ライブラリ、および 30 個の動的ライブラリをリンクする場合、gcc はどのようにリンクすべきでしょうか?

ここに画像の説明を挿入

Linux コマンド (61) - ldd コマンド (csdn ブロガー Lian Miao Big Carp の記事から転載)

2.
したがって、gcc のデフォルトのダイナミック リンクは単なる推奨オプションであり、それがダイナミック リンクであるかスタティック リンクであるかは、提供されるライブラリがダイナミック ライブラリであるかスタティック ライブラリであるかによって異なります
動的ライブラリのみが提供され、オプションを指定しない場合、それは動的リンクになります。ただし、コンパイルに -static オプションが含まれている場合、この時点でコンパイルとリンクが失敗し、エラーが報告され、コンパイルとリンクを実行できません。
静的ライブラリのみを提供し、オプションがない場合、gcc は静的にのみリンクできます。もちろん、 -static オプションを使用する場合は、より標準的な方法になります。
動的ライブラリと静的ライブラリの両方が gcc に与えられ、この時点で -static オプションを使用してコンパイルすると、それは静的リンクになります。お持ちでない場合は、ダイナミック リンクです。

3.
リンクされたライブラリの 1 つがダイナミック ライブラリである限り、gcc によって提供される最後のリンク方法はダイナミック リンクです。
実行可能プログラム mymath は、自分で作成した静的ライブラリ libmymath.a をリンクするだけでなく、C 言語の動的ライブラリ libc.so.6 もリンクします。したがって、最後のリンク方法は動的リンクです。

2.4 ライブラリ パスをシステムのデフォルト パスにコピーします (インストールの本質はコピーすることです)

1.
ライブラリのパスをシステムのデフォルトのパスにコピーします。これは基本的にインストールです。コピー = インストール

ここに画像の説明を挿入
2.
ライブラリをシステムのデフォルトのパスにコピーしたとしても、コンパイル時にリンク ライブラリ ファイルの名前を指定しないと、同じ接続エラーが報告され、関数への未定義の参照が報告されます。上で述べた理由は、ヘッダー ファイルのソース コードは特定のヘッダー ファイルにリンクするように指示しますが、ライブラリ ファイルには誰も指示しません。また、リンクするのは標準ライブラリではなくサードパーティ ライブラリであるため、少なくともコンパイル時に-lオプションを追加する必要があります

ここに画像の説明を挿入

3.
システムのデフォルト パスの下にあるライブラリ パスを削除します。これにより、実際にはアンインストールされます。
自分で書いたテストコードをシステムのデフォルトパスにコピーすることは推奨されません、システムのデフォルトパスにあるライブラリは厳密にテストされており、リリースバージョン、セキュリティと実用性などのシステムプロセスがテストされています。自分で書いたテストコードだけでは十分ではないので、システムのデフォルトのパスにコピーしないでください。

ここに画像の説明を挿入

6. ダイナミック ライブラリとダイナミック リンク (gcc -shared はダイナミック ライブラリを生成します)

1. 位置に依存しないコードとアーカイブ .o ファイルを生成して、ダイナミック ライブラリを形成します (gcc -fPIC -c *.c および gcc -shared -o libxxx.so *.o)

gcc -fPIC -c *.c  ---生成.o文件
gcc -shared -o libmymath.so *.o  ---.o文件进行归档形成动态库

共有: 共有ライブラリ形式を生成することを意味します。
fPIC: 位置非依存コード (位置非依存コード) を生成します。
ライブラリ名規則: libxxx.so

ここに画像の説明を挿入

2. プログラムの実行中、ダイナミック ライブラリをロードするときに、OS とシェルがライブラリ ファイルを見つけることができません (4 つの解決策)

1.
次に、ライブラリ ファイルとヘッダ ファイルをパッケージ化して、mylib ディレクトリに置きます。必要に応じて、このディレクトリを圧縮してライブラリ ユーザーに渡します。ダウンロードして解凍した後、ユーザーはライブラリ ファイルとヘッダ ファイルを取得できます。 。

ここに画像の説明を挿入
2.
ダイナミック ライブラリの使用方法はスタティック ライブラリと非常に似ており、コンパイル時に対応するオプションを指定して実行可能プログラム mymath を生成できます。
しかし、このプログラムを実行すると問題が発生します。mymathプログラムは確かに動的にリンクされていますが、システムはダイナミック ライブラリの libmymath.so ファイルを見つけることができません。

ここに画像の説明を挿入
ここに画像の説明を挿入

3.
コンパイル時に、gcc はライブラリ ファイルのパスと名前を認識しますが、プログラムの実行時には gcc とは何の関係もありません。ダイナミック ライブラリはプログラムの実行中にロードされ、実行中に OSとシェルは、ライブラリがシステム パスにないため、ライブラリがどこにあるかを知りません。そのため、OS はライブラリを見つけることができません

2.1 環境変数 LD_LIBRARY_PATH にライブラリ パスを追加します (永続的ではなく、一時的にのみ)

1.
プログラムの実行中、シェルはシステムのデフォルト パスだけでなく、環境変数 LD_LIBRARY_PATH でもライブラリを検索します。そのため、ダイナミック ライブラリ ファイルのパスが環境変数に追加されている限り、問題が発生する可能性があります。解決される。

2.
ldd の表示内容から、OS がライブラリファイルのパスを見つけたことがわかります。

ここに画像の説明を挿入

2.2 /etc/ld.so.conf.d/ ディレクトリに構成ファイルを追加し、手動で ldconfig を呼び出して更新します。

1.
ただし、次回 xshell にログインすると、環境変数に追加したパスはデフォルトで自動的に消えるため、次回ログインすると mymath は正常に実行できなくなり、エラーが報告されます。ライブラリファイルが見つからない場合 パスを永続的に有効にしたい場合は、環境変数の設定ファイルを変更する必要があります この設定ファイルを変更するのは非常に面倒なので、環境変数の解決策の方が適しています通常のテスト用であり、このログインでは一時的に有効です。

2.
まず /etc/ld.so.conf.d/ と入力すると、ディレクトリ内に多くの設定ファイルがあり、ダイナミック ライブラリのパスがこれらのディレクトリに保存されていることがわかります。をファイルに作成し、このファイルを /etc/ld.so.conf.d/ ディレクトリに置くと、OS とシェルがライブラリ ファイルを見つけることができます。

ここに画像の説明を挿入

ここに画像の説明を挿入
3.
構成ファイルを追加した後も、実行可能プログラムのダイナミック ライブラリ ファイルがまだ見つからないことがわかります。実際には、まだ 1 つの手順が残っています。新しいダイナミック リンクをインストールしたため、手動で ldconfig を呼び出す必要があります。したがって、システムに通知する、つまりリフレッシュする必要があるため、リフレッシュ後にプログラムは正常に実行でき、プログラムの実行中にダイナミック ライブラリを正常にリンクできます

ここに画像の説明を挿入

Linux: ldconfig の使い方 (csdn blogger technology explorer の記事より転載)

2.3 システムまたは現在のパスの下に、ダイナミック ライブラリ ファイルのソフト リンクを作成します。

1.
プログラムの実行中、システムは現在のパスでリンクする必要があるダイナミック ライブラリ ファイルを検索します。その後、ソフト リンクを通じてダイナミック ライブラリ ファイルへのショートカットを作成し、システムが操作中にショートカットを通じて対応するダイナミック ライブラリ ファイルを参照する ダイナミック ライブラリ ファイル。

ここに画像の説明を挿入
2.
現在のパスの下にソフト リンクを確立することに加えて、システム パスの下にもソフト リンクを確立することもできます。これにより、OS はプログラムの実行中にダイナミック ライブラリ ファイルを見つけることもできます。

ここに画像の説明を挿入

2.4 ダイナミック ライブラリ ファイルのパスをシステムのデフォルト パスにコピーします (端的に言うと、ダイナミック ライブラリをインストールします)。

このソリューションの詳細については説明しません。比較的単純です。cp を実行し、コマンドの実行時に sudo オプションを指定するだけです。ただし、ダイナミック ライブラリはライブラリと比較的簡単に比較できるため、これはお勧めできません。他のシステムと同様であるため、動的ライブラリをむやみにインストールしないでください。

3. 他のサードパーティライブラリ ncurses をインストールします。

[wyn@VM-8-2-centos Use_libraries]$ sudo yum install -y ncurses-devel

1.
ncurses ライブラリをインストールした後、システムのデフォルトのヘッダー ファイルとライブラリ ファイルのパスで、ダウンロードした ncurses ライブラリのヘッダー ファイルとライブラリ ファイルを見つけることができます。

ここに画像の説明を挿入
2.
以下は、ncurses ライブラリを使用したデモ コードです。vim 上でも再生できます。コードをコンパイルするときは、gcc ライブラリの名前を指定する必要があります。そうしないと、関数への未定義の参照という接続エラーが報告されます。

//test.c
 
#include <string.h>
#include <ncurses.h>
 
int main()
{
    
    
    initscr();
    raw();
    noecho();
    curs_set(0);
 
    const char* c = "Hello, World!";
 
    mvprintw(LINES/2,(COLS-strlen(c))/2,c);
    refresh();
 
    getch();
    endwin();
 
    return 0;
}

以下はデモコードを実行した結果です
ここに画像の説明を挿入

Curses ncurses ライブラリのインストールの紹介 (csdn blogger whatday の記事より転載)

7. 動的および静的ライブラリのロード プロセスの深い理解 (絶対アドレス指定、相対アドレス指定: fPIC は位置に依存しないコードを生成します)

1.
スタティック ライブラリをロードする必要はありません。プログラムをロードするとき、つまりコンパイルとリンクを行うとき、スタックとヒープがないため、システムはスタティック ライブラリのコードを実行可能プログラムのコード セグメントにコピーします。実行可能プログラム内のセグメント、コード セグメント、データ セグメント (.data セグメントと .rodata セグメントに分割可能)、および BSS セグメントのみ
したがって、物理メモリには、静的ライブラリのコードが存在する必要があります。静的ライブラリのコードは、実行可能プログラムの一部としてメモリの仮想アドレス空間にロードされ、その後、物理メモリにマッピングされるためです。ページ テーブルの場合、物理メモリには静的ライブラリ コードのアドレスが含まれます。このようなロード スキームは絶対アドレス指定スキームです。

ここに画像の説明を挿入

プログラムまたは - メモリ領域の割り当て (5 セグメント) - ついに判明 (csdn ブロガー helmsgao の記事より転載)

2.
ダイナミック ライブラリは、スタティック リンクとは異なり、実行可能プログラムで使用されるライブラリ関数のオフセット アドレスを実行可能プログラムにコピーするだけであり、ダイナミック ライブラリ内のすべてのライブラリ関数のアドレス指定スキームは、相対アドレス指定開始: オフセット アドレス方式を採用しています。CPU がコードを実行すると、物理メモリに外部アドレスがあることがわかります。この外部アドレスは、コンパイルおよびリンクの段階でのダイナミック ライブラリ内の関数のオフセット アドレスです。ダイナミック ライブラリは物理メモリにロードされます。 (ダイナミック ライブラリをロードするときに何をロードする必要があるか)、ダイナミック ライブラリが共有にマップされると、OS はページ テーブルを通じて物理メモリ内のダイナミック ライブラリの場所を仮想アドレス空間の共有領域にマップします。領域にある場合、このライブラリの開始アドレスはすぐに決定されますが、マッピングが完了すると、仮想アドレス空間にライブラリ関数のオフセットが存在するのではありませんか? 次に、仮想アドレス空間のコンテキストで直接ジャンプし、共有領域にジャンプします。これで、ライブラリの開始アドレスと特定のライブラリ関数のオフセットが得られるので、共有領域で簡単にアクセスできるようになります。バイナリを検索します。ライブラリ関数のコードを選択して実行し、実行が完了したら、そのコード セグメントにジャンプし、残りのコードを逆方向に実行し続けます。

3.
これは、.o ファイルを動的に生成するときに、gcc コンパイルに -fPIC オプションを追加する必要があることも説明できます。これにより、動的ライブラリ内の関数がアドレス指定に相対アドレス スキームを使用できるようになり、後続のプログラムの実行時 動的リンク プロセス

4.
.o ファイルをパッケージ化するとき、gcc は -shared オプションを使用してダイナミック ライブラリの特定の形式を形成します。これは、オペレーティング システムが後でダイナミック ライブラリをライブラリの形式でメモリにロードするのに便利です。次に、ページ テーブルを介して共有領域にマッピングされ、ライブラリの開始アドレスが決定され、コード セグメントが共有領域にジャンプし、ライブラリ関数のオフセットと開始アドレスを取得し、対応するライブラリ関数のバイナリ コードを実行して、Return にジャンプします。コードセグメントに追加して、残りのバイナリコードを実行します。

5.
100 個のプログラムが静的ライブラリを使用すると仮定すると、プロセス ローテーションに関与する 100 個のプロセスはすべて、プロセス間で共有されるのではなく、独自の静的ライブラリ コードを持ちます。
また、100 個のプログラムがダイナミック ライブラリを使用する場合、物理メモリに必要なダイナミック ライブラリ コードのコピーは 1 つだけであり、プロセス ローテーションに含まれる 100 個のプロセスは、物理メモリ上でダイナミック ライブラリの 1 つのコピーを共有するだけで済みます。

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/erridjsis/article/details/128797445