相違点: 1. ダイナミック ライブラリのサフィックスは「.so」、スタティック ライブラリのサフィックスは「.a」です。動的関数ライブラリが変更された場合、プログラムを再コンパイルする必要はありませんが、静的関数ライブラリが変更された場合、プログラムを再コンパイルする必要があります。 3. 動的ライブラリは、静的ライブラリと比較して、コンパイル時にターゲットコードにコンパイルされず、ユーザプログラムは、関数実行時に関数ライブラリ内の対応する関数を呼び出すだけであるため、動的関数ライブラリによって生成される実行ファイルは小さくなります。 。
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
1. メモリとディスク領域の無駄:
静的リンク方法は、次のような場合には適していません。コンピュータメモリとディスク スペースの無駄遣いは非常に深刻です。 C 言語の静的ライブラリのサイズが 1MB で、そのライブラリを使用する必要があるファイルがシステム内に 100 個あるとします。静的リンクを使用すると、100M のメモリが無駄になります。数値がそれより大きくなると無駄になります。たとえば、以下に示すように、プログラム 1 とプログラム 2 の両方で Lib.o を使用する必要があります。静的リンクが使用される場合、このファイルの 2 つのコピーが物理メモリに保存されます。
2. アップデートに関するトラブル:
たとえば、プログラムが 20 個のモジュールで構成され、各モジュールのサイズが 1MB の場合、アップデート時にどのモジュールを使用する場合でも、ユーザーは 20MB プログラム全体を再ダウンロードする必要があります。
3. ダイナミック ライブラリとダイナミック リンク<1>ダイナミック ライブラリ:
プログラムは次の場所にのみ移動します。動的ライブラリをリンクするコードと、複数のプログラムで共有されるライブラリのコード。ダイナミック ライブラリにリンクされた実行可能ファイルには、外部関数が配置されているターゲット ファイルのマシン コード全体ではなく、使用する関数のエントリ アドレスのテーブルのみが含まれています。
注: 動的ライブラリの命名形式: lib "ライブラリ名" .so (サフィックス) 例: libadd.so は、add
<2>という名前の動的ライブラリです。ダイナミック リンク:メモリの無駄やモジュールの更新の難しさなどを考慮して、静的リンクの代わりに動的リンクが提案されています。基本的な実装の考え方は、静的リンク実行ファイルのようにすべてのプログラム モジュールを単一のプログラム モジュールにリンクするのではなく、プログラムをモジュールごとに比較的独立した部分に分割し、プログラムの実行時にそれらをリンクして完全なプログラムを形成することです。したがって、動的リンクは、実行時までリンクプロセスを延期します。
同样,假如有程序1,程序2,和Lib.o三个文件,程序1和程序2在执行时都需要用到Lib.o文件,当运行程序1时,系统首先加载程序1,当发现需要Lib.o文件时,也同样加载到内存,再去加载程序2当发现也同样需要用到Lib.o文件时,则不需要重新加载Lib.o,只需要将程序2和Lib.o文件链接起来即可,内存中始终只存在一份Lib.o文件。
动态库和动态链接的例子依然使用上面的代码,输出结果也相同,唯一需要改变的就是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命令查看该可执行文件所依靠的动态库。
Windows和Linux下库文件后缀不同的根本原因是两者文件格式不同。在Linux系统中,我们可以通过使用file命令来检测动态库的文件类型,而其实这些动态库都是以ELF格式存储的。ELF动态链接文件被称为动态共享对象(DSO,Dynamic Shared Objects),简称共享对象;在windows下,动态链接文件被称为动态链接库(Dynamic Linking Library),也就是.dll文件后缀的全称。
优点:
①毋庸置疑的就是节省内存;
②减少物理页面的换入换出;
升级某个模块时,通常只需覆盖对应的旧目标文件。新版本的目标文件会被自动装载到内存中并且链接起来;
④程序在运行时可以动态的选择加载各种程序模块,实现程序的扩展。
四、静态库和动态库的区别
1. 静态库
这类库的名字一般是 libxxx.a ;利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。如果静态函数库发生更改,那么你的程序需要重新编译,所以这也会成为他的不足之处。
2. 动态库
这类库的名字一般是 libxxx.so ;相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。为使程序能够正常运行,需要在程序的运行环境中提供相应的函数库,因为该库无法被整合进程序,而是在程序运行时动态地申请和调用。动态函数库的更新方便,因为它的修改不会影响你的程序。
以上がLinux におけるスタティック リンク ライブラリとダイナミック リンク ライブラリの違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。