Linuxの動的ライブラリと静的ライブラリ

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

ソフトリンク

ローカル パスで実行していない場合、実行対象のバイナリ ファイルは通常、プログラム パスを指定する必要があります。ただし
ここに画像の説明を挿入
、パスが複雑なプログラムの場合、この種の実行は非常に時間がかかります。操作を容易にするために、実行可能プログラムのパスをソフト リンクとして設定できます。このときのソフト リンクは、通常、Windows 実行可能プログラムへのショートカットとみなすことができます。

ソフト リンクを作成するコマンドは次のとおりです

[yzh@VM-4-5-centos ~]$ ln -s /home/yzh/my.exe mysoft

ここに画像の説明を挿入
注意:
ソフトリンクを作成する場合、実行可能プログラムのパスを間違って記述することはできません。間違ったパスを記述すると、プログラムの実行時にエラーが発生します。

ハードリンク

ハード リンクとは、ファイル名と、指定されたディレクトリ内のターゲット i ノード ファイルとの間のマッピング関係の確立を指し、通常、デフォルトは「エイリアス」です。

ハードリンクを作成するコマンドは次のとおりです

[yzh@VM-4-5-centos ~]$ ln /home/yzh/my.exe myhard

ここに画像の説明を挿入

ハードリンクの目的

inode には、ターゲット ファイルに関連付けられたファイル名の数を表す参照カウントも存在することがわかっています。

  • ハードリンクを作成すると、ターゲットファイルにもう 1 つのファイル名が関連付けられ、参照カウントが +1 されることを意味します。
  • ハード リンクを削除すると、ターゲット ファイルに関連付けられるファイル名が 1 つ減り、参照カウントが -1 になります。
  • 参照カウントが 0 になると、対象ファイルにファイル名が関連付けられていないことになり、実際にファイルが削除されたことになります。

リンク関係の削除コマンド:

[yzh@VM-4-5-centos ~]$ unlink myhard

ここに画像の説明を挿入

拡張アプリケーション

空のディレクトリを作成すると、ファイルの参照カウントが 2 になるのはなぜですか?
ここに画像の説明を挿入
それ自体のディレクトリ名とその中の " . " は、同じファイルの i ノードとのマッピング関係があるからです。このうち、" . " は現在のディレクトリ (つまり、今いるディレクトリ) も表します。別の例: ceshi ディレクトリに ceshi1 ディレクトリを作成するときに、そのディレクトリに入り、ll -ail ディレクトリを使用して表示すると、このディレクトリ内の "..." がそのファイルの i ノードと同じであることがわかります。このうち、「…」は上位ディレクトリも表します
ここに画像の説明を挿入

ここに画像の説明を挿入
したがって、ターゲット ディレクトリの参照カウント -2 (自己対応と次のレベルのディレクトリの ".") を使用して、ディレクトリ内のサブディレクトリの数を決定できます (サブディレクトリ内の "..." の数も表します)。

ソフトリンクとハードリンクの違い

作成されたソフト リンクとハード リンクを見ると、違いは次のとおりです

  • ソフト リンクには独立した i ノードがあり、ソフト リンクが独立したファイルであることを示します。
  • ハード リンクには独立した i ノードがありません。これは、ハード リンクが独立したファイルではないことを示しています。
    ここに画像の説明を挿入

動的ライブラリと静的ライブラリ

理解を容易にするために、2 つのソース ファイルと 2 つのヘッダー ファイルを作成しました。これらは、動的ライブラリと静的ライブラリの関連操作にのみ使用されます。

mymath.c

目標値まで積み上げていきます。

#include "mymath.h"                                                                                            
int addToTarget( int form,int to )
 {
    
    
           int sum = 0;
 
           for( int i = form; i <= to; ++i )
            {
    
    
              sum += i;
            }
            return sum;
 }

mymath.h

 #pragma once
 #incldue <stdio.h>
 extern int addToTarget( int from, int to );

マイプリント.c

指定された文字列とタイムスタンプを出力します。

#include "myprint.h"
void Print( const char* str )
{
    
    
   print("%s[%d]\n",str,(int)time(NULL));
}

マイプリント.h

#pragma once
#include <time.h>
extern void Print( const char* str);

main.c

myprint および mymath 関連ライブラリを呼び出します。

#include "myprint.h"                                                                                                #include "mymath.h"
int main()
  {
    
    
    Print("hello world\n");
    int res = addToTarget(1,100);
    printf("%d\n",res);
    return 0; 
 }

静的ライブラリ

静的ライブラリを生成する

1. すべてのソース ファイルからバイナリ ファイルを生成します (実行可能ではありません)。
ここに画像の説明を挿入

2. rc コマンドを使用して、これらのバイナリ ファイルを静的ライブラリにパッケージ化します。

  • -r(replace): 作成したターゲットファイルが静的ライブラリファイルと同名の場合、同名の静的ライブラリファイルを新しい静的ライブラリファイルに置き換えます。
  • -c(create): スタティック ライブラリを作成します
    ここに画像の説明を挿入
    3: ヘッダ ファイルとスタティック ライブラリを指定されたディレクトリのスタティック ライブラリに配置します。
    ここに画像の説明を挿入

もちろん、上記の操作を簡略化するために、Makefile を使用して均一に生成することもできます。make
ここに画像の説明を挿入
および makeoutput コマンドを使用して、静的ライブラリの生成とパッケージ化に同意します。
ここに画像の説明を挿入

静的ライブラリの使用

方法 1 : sudo cp コマンドを使用して、ヘッダー ファイルを /usr/include にコピーし、静的ライブラリ ファイル: /lib64 をコピーします。ただし、gcc コマンドを使用してコンパイルし、数十の実行可能プログラムにリンクする場合は、コンパイルするライブラリを指定する必要があります (ライブラリ名から接頭辞と接尾辞を削除するだけです) 例: libhello.a --> hello. 方法 2: ヘッダー ファイルと静的ライブラリ ファイルのパスを直接指定し、コンパイラは指定されたパスを検索します。コンパイルコマンドは次
ここに画像の説明を挿入
とおり
ここに画像の説明を挿入
です

gcc main.c -I ./output/include/ -L ./output/lib -lhello
  • -I: ヘッダファイルの検索パスを指定することを示します。
  • -L: ライブラリファイルの検索パスを指定することを示します。
    ここに画像の説明を挿入

ダイナミックライブラリ

動的ライブラリの生成

方法 1 :

最初のステップ: まず、ソース ファイルをバイナリ ファイル (実行可能ファイルではありません) にコンパイルします。

gcc -fPIC -c mymath.c -o mymath.o -std=c99
gcc -fPIC -c myprint.c -o myprint.o -std=c99

ここに画像の説明を挿入
ステップ 2 : gcc -shared コマンドを使用してすべてのオブジェクト ファイルをパッケージ化し、動的ライブラリを生成します

gcc -shared myprint.o mymath.o -o libhello.so

ここに画像の説明を挿入

ステップ 3 : 指定したディレクトリ内のヘッダー ファイルと静的ライブラリを統合する

出力ディレクトリの下のインクルードに .h ヘッダー ファイルを配置し、インクルード ディレクトリの下の lib ディレクトリにダイナミック ライブラリの .so ファイルを配置することを選択します。方法 2: Makefile を使用してパッケージ化し、均一に生成します
ここに画像の説明を挿入

動的ライブラリと静的ライブラリをパッケージ化して生成するためのすべてのコマンドを Makefile に書き込み、Makefile コマンドを使用して動的ライブラリと静的ライブラリを生成します。
ここに画像の説明を挿入
ここに画像の説明を挿入

動的ライブラリの使用

与动态库的使用不同的是,我们使用gcc -I -L -l编译链接产生的可执行程序不可以直接运行.
ここに画像の説明を挿入
原因:我们在gcc 使用 -I -L 表明动态库的路径时,是对gcc编译器说的,当我们要运行加载程序的时候,此时已经生成了可执行程序,跟gcc没有任何关系,但是要运行时,进程需要通过->虚拟地址空间->页表映射去寻找动态库的位置,所以我们要对Linux系统表明动态库的位置.,静态库不需要将库的地址告诉操作系统是因为静态库在加载的时候已经将代码加载到内存中了,不需要再去与操作系统建立映射关系查找.

方法 1 : 環境変数を増やす

LD_LIBRARY_PATH はプロセスがダイナミック ライブラリを実行するときに検索されるパスであるため、ダイナミック ライブラリのパスを LD_LIBRARY_PATH 環境変数に追加する必要があります。

環境変数LD_LIBRARY_PATHにexportとダイナミックライブラリの絶対パスを指定し、echoコマンドで環境変数が正常に追加されたか確認してください。

[yzh@VM-4-5-centos userlib]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/yzh/userlib/output.lib

ここに画像の説明を挿入

方法 2 : /etc/ld.so.conf,d/ ファイルを構成する

ステップ 1: /etc/ld.so.conf, d/ ディレクトリにファイルを作成します (接尾辞は .conf である必要があります)。

[yzh@VM-4-5-centos userlib]$ sudo vim /etc/ld.so.conf.d/yzh.conf

ここに画像の説明を挿入
このファイルにダイナミック ライブラリのパスを追加し、
ここに画像の説明を挿入
sudo ldconfig コマンドを使用して /etc/ld.so.conf.d/ の下のディレクトリ ファイルを更新します。
ここに画像の説明を挿入
方法 3 : ソフト リンクを設定する

/lib64/ の下にダイナミック ライブラリのパスをソフト リンクとして設定します。ソフト リンクとハード リンクを設定する際には、ダイナミック ライブラリの絶対パスを指定するのが最善です。そうしないと、システムはダイナミック ライブラリを見つけられません。

[yzh@VM-4-5-centos userlib]$ sudo ln -s /home/yzh/userlib/output/lib/libhello.so /lib64/libhello.so

ここに画像の説明を挿入
この時点で、ls /lib64 を使用してソフト リンクが確立されているかどうかを確認します。
ここに画像の説明を挿入

動的ライブラリと静的ライブラリの違い

  • 静的ライブラリを使用すると、実行可能プログラムがメモリにロードされ、ページテーブルを介してアドレス空間のコード領域にマッピングされ、プログラムを実行する各プロセスが繰り返しプログラムをメモリにロードすることになり、メモリ空間が大幅に浪費されます

  • ダイナミックライブラリは、実行プログラムと一括してロードできます。実行プログラム内のダイナミックライブラリをプロセスが実行すると、プロセスはダイナミックライブラリをメモリにロードし、メモリはページテーブルを介してアドレス空間のスタックとヒープの共有領域にマッピングされます。プロセスがダイナミックライブラリを実行する際、コード領域から共有領域にジャンプして実行されます。実行プログラムのダイナミックライブラリを実行するプロセスが複数ある場合、このときメモリにロードされるダイナミックライブラリは各プロセスで共有されます。したがって、動的ライブラリは共有ライブラリとも呼ばれます。
    ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/m0_63300413/article/details/131754814