ホームページ  >  記事  >  運用・保守  >  Linux におけるスタティック リンク ライブラリとダイナミック リンク ライブラリの違いは何ですか?

Linux におけるスタティック リンク ライブラリとダイナミック リンク ライブラリの違いは何ですか?

青灯夜游
青灯夜游オリジナル
2023-02-06 15:09:362097ブラウズ

違い: 1. ダイナミック ライブラリのサフィックスは「.so」、スタティック ライブラリのサフィックスは「.a」です。 2. 静的関数ライブラリを変更した場合、プログラムを再コンパイルする必要がありますが、動的関数ライブラリの変更はプログラムには影響しません。 3. 動的ライブラリは、静的ライブラリと比較して、コンパイル時にターゲットコードにコンパイルされず、ユーザプログラムは、関数実行時に関数ライブラリ内の対応する関数を呼び出すだけであるため、動的関数ライブラリによって生成される実行ファイルは小さくなります。 。

Linux におけるスタティック リンク ライブラリとダイナミック リンク ライブラリの違いは何ですか?

#このチュートリアルの動作環境: linux7.3 システム、Dell G3 コンピューター。

1. ライブラリの基本概念:

Windows プラットフォームと Linux プラットフォームの両方に多数のライブラリがあります。基本的に、ライブラリは、実行のためにオペレーティング システムによってメモリにロードできる実行可能コードのバイナリ形式です。 Windows と Linux の性質が異なるため、2 つのライブラリのバイナリには互換性がありません。平たく言えば、プログラマーの便宜のために、これらの一般的に使用される関数のターゲット ファイルをパッケージ化し、対応する関数のインターフェイスを提供することを意味します。関数を使用する場合、対応するヘッダー ファイルをインクルードするだけで済みます。ライブラリは用途に応じて動的ライブラリと静的ライブラリに分けられ、対応するサフィックスもプラットフォームごとに異なります。

WINDOWS の場合: .dll 接尾辞は動的ライブラリ、.lib 接尾辞は静的ライブラリ;

LINUX の場合: .so 接尾辞は です動的ライブラリ、.a サフィックスは静的ライブラリです。

#2. 静的ライブラリと静的リンク

##静的ライブラリ:

静的ライブラリは、単純にターゲット ファイルのコレクション、つまり、多数のターゲット ファイルを圧縮およびパッケージ化して形成されたファイルとみなすことができます。たとえば、日常的なプログラミングでは、printf 関数を使用する必要がある場合は stdio.h ライブラリ ファイルをインクルードする必要があり、strlen を使用する場合は string.h ライブラリ ファイルをインクルードする必要がありますが、 .o を形成する対応する関数のソース コード ファイルを直接提供すると、管理と使用に多大な不便が生じるため、「ar」圧縮プログラムを使用してこれらのターゲット ファイルをまとめて圧縮し、静的ライブラリ ファイル libx.a を形成できます。

注: 静的ライブラリの命名形式: lib "ライブラリ名" .a (サフィックス) 例: libadd.a は、add

という静的ライブラリです。静的リンク :

静的ライブラリの場合、プログラムがコンパイルおよびリンクされると、ライブラリ コードが実行可能ファイルにリンクされるため、プログラムの実行中に静的ライブラリは必要なくなります。使用中に必要なのは、プログラムのライブラリとコンパイルされたファイルをリンクして実行可能ファイルを形成することだけです。

例を挙げて、ヘッダー ファイルと自分で作成したコードを同時にコンパイルおよびリンクし、最終的に実行可能ファイルを生成する方法を学びましょう:

/main.c/

#include <stdio.h>
#include "add.h"

int main()
{
	int ret = add(3, 4);
	printf("3 + 4 = %d\n",ret);

	return 0;
}

/add.c/

#include "add.h"

int add( int x, int y)
{	
	return x + y;
}


/add.h/

#pragma once
#include <stdio.h>

int add( int x, int y);

/Makefile/

main : main.c libadd.a
	gcc main.c -L . -ladd -o main
	//-L为指定路径 .为当前目录下 -l+库名字,编译器可在指定目录下自己寻找名为add的库文件
	
libadd.a : 
	gcc -c add.c -o add.o
	
	//ar -rc将多个编译后的文件打包为一个静态库文件
	ar -rc libadd.a add.o

.PHONY:clean
clean:
	rm main libadd.a

make 後のスクリーンショットの出力:

Linux におけるスタティック リンク ライブラリとダイナミック リンク ライブラリの違いは何ですか?##欠点:

1. メモリとディスク領域の無駄: 静的リンク方法は、次のような場合には適していません。コンピュータ

メモリとディスク スペースの無駄遣いは非常に深刻です。

C 言語の静的ライブラリのサイズが 1MB で、そのライブラリを使用する必要があるファイルがシステム内に 100 個あるとします。静的リンクを使用すると、100M のメモリが無駄になります。数値がそれより大きくなると無駄になります。たとえば、以下に示すように、プログラム 1 とプログラム 2 の両方で Lib.o を使用する必要があります。静的リンクが使用される場合、このファイルの 2 つのコピーが物理メモリに保存されます。

2. アップデートに関するトラブル: Linux におけるスタティック リンク ライブラリとダイナミック リンク ライブラリの違いは何ですか?

たとえば、プログラムに 20 個のモジュールがあり、各モジュールのサイズは 1MB しかない場合、モジュールをアップデートするたびに、ユーザーは 20M プログラムを再ダウンロードする必要があります。

3. ダイナミック ライブラリとダイナミック リンク

ダイナミック ライブラリ:

ダイナミックライブラリのコードはプログラムの実行中にリンクされ、ライブラリのコードは複数のプログラムで共有されます。ダイナミック ライブラリにリンクされた実行可能ファイルには、外部関数が配置されているターゲット ファイルのマシン コード全体ではなく、使用する関数のエントリ アドレスのテーブルのみが含まれています。

注: 動的ライブラリの命名形式: lib "ライブラリ名" .so (サフィックス) 例: libadd.so は、add

という名前の動的ライブラリです。ダイナミック リンク:

静的リンクではメモリの浪費やモジュール更新の困難などの問題があるため、動的リンクが提案されています。基本的な実装の考え方は、静的リンク実行ファイルのようにすべてのプログラム モジュールを単一のプログラム モジュールにリンクするのではなく、プログラムをモジュールごとに比較的独立した部分に分割し、プログラムの実行時にそれらをリンクして完全なプログラムを形成することです。したがって、動的リンクは、実行時までリンクプロセスを延期します。

同样,假如有程序1,程序2,和Lib.o三个文件,程序1和程序2在执行时都需要用到Lib.o文件,当运行程序1时,系统首先加载程序1,当发现需要Lib.o文件时,也同样加载到内存,再去加载程序2当发现也同样需要用到Lib.o文件时,则不需要重新加载Lib.o,只需要将程序2和Lib.o文件链接起来即可,内存中始终只存在一份Lib.o文件。
Linux におけるスタティック リンク ライブラリとダイナミック リンク ライブラリの違いは何ですか?
动态库和动态链接的例子依然使用上面的代码,输出结果也相同,唯一需要改变的就是Makefile文件。

/Makefile/
main : main.c libadd.so
	gcc main.c -L . -ladd -o main

libadd.so : 
	gcc -fPIC -shared add.c -o libadd.so
	//-shared表示输出结果是共享库类型的  -fPIC表示使用地址无关代码奇数来生产输出文件
	
.PHONY:clean
clean:
	rm main libadd.so
  • 当我们生成可执行文件后,可使用ldd命令查看该可执行文件所依靠的动态库。

Linux におけるスタティック リンク ライブラリとダイナミック リンク ライブラリの違いは何ですか?

  • 前面提到windows和Linux下库文件的后缀不同,更根本的原因在于二者文件格式都不同。可以通过file一个动态库查看Linux下动态库的文件类型其实是ELF格式。ELF动态链接文件被称为动态共享对象(DSO,Dynamic Shared Objects),简称共享对象;在windows下,动态链接文件被称为动态链接库(Dynamic Linking Library),也就是.dll文件后缀的全称。

优点

  • ①毋庸置疑的就是节省内存;

  • ②减少物理页面的换入换出;

  • ③在升级某个模块时,理论上只需要将对应旧的目标文件覆盖掉即可。新版本的目标文件会被自动装载到内存中并且链接起来;

  • ④程序在运行时可以动态的选择加载各种程序模块,实现程序的扩展。

四、静态库和动态库的区别

1. 静态库 

这类库的名字一般是 libxxx.a ;利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为 如果静态函数库改变了,那么你的程序必须重新编译 。 

2. 动态库 

这类库的名字一般是 libxxx.so ;相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。 动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。

相关推荐:《Linux视频教程

以上がLinux におけるスタティック リンク ライブラリとダイナミック リンク ライブラリの違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。