序文
コンテンツ
1.ライブラリがあるのはなぜですか2.静的
ライブラリ2.1同じ名前
の.oファイルに.cファイルを
生成します
-
静的ライブラリ(.a):プログラムは、プログラムのコンパイルとリンク時にライブラリのバイナリコードをプログラムの実行可能ファイルにコピーし、プログラムの実行時に静的ライブラリは不要になります。
-
ダイナミックライブラリ(.so):ダイナミックライブラリのコードは、プログラムの実行中にのみリンクされ、ライブラリのコードは複数のプログラムで共有されます
c言語ライブラリなど:
- ダイナミックライブラリlibc.so
- 静的ライブラリlibc.a
ライブラリの命名規則は次のとおりです。libヘッダー+ライブラリ名+サフィックスプレフィックスlibを削除し、。サフィックスを削除し、残りはライブラリ名です。
実行可能プログラムを生成するには、動的リンクと静的リンクの2つの方法があります。
ldd filename # 查看链接方式
1.なぜ図書館があるのですか
開発時には、他の人のソースコードのコンパイル、他の人から提供されたサードパーティライブラリの呼び出し、他の人から提供されたネットワーク関数インターフェイスの呼び出しなど、他の人が作成したコードを使用することがよくあります...
なぜ他人のコードを使用する必要があるのですか?
- 開発効率を向上させる
- プログラムの堅牢性を向上させる
いわゆるロバスト性とは、プログラムのロバスト性を指し、各モジュール間の結合は低いです。サードパーティのライブラリについては、問題はないと思います。私のプログラムにエラーがある場合、呼び出されたライブラリ自体に問題があることを疑う必要はありませんが、自分で作成したコードロジックに問題があるはずです。これにより、エラーの範囲が狭くなります。チェックしました。もちろん、ここでのライブラリは、STLなどの標準ライブラリなどの信頼できるライブラリを参照する必要があります。
さて、他の人のコードを使用する方法、ライブラリをパッケージ化して使用する方法を学ぶことは非常に重要です
2.静的ライブラリ
この実験では、5つの元のファイルがあります。
add.h
add.c
sub.h
sub.c
main.c
#pragma once
#include <stdio.h>
int add(int x, int y);
#include "add.h"
int add(int x, int y) {
return x+y;
}
#pragma once
#include <stdio.h>
int sub(int x, int y);
#include "sub.h"
int sub(int x, int y) {
return x-y;
}
#include <stdio.h>
#include "add.h"
#include "sub.h"
int main() {
printf("%d\n%d\n", add(20, 10), sub(20, 10));
return 0;
}
2.1.cファイルを同じ名前の.oファイルに生成します
静的ライブラリを呼び出すとは、プログラムがリンクされているときに静的ライブラリのバイナリコードを実行可能ファイルにリンクすることを意味します。これにより、実行時に静的ライブラリを見つける必要がなくなります。
さて、静的ライブラリはリンクステップで実行可能ファイルにリンクされているので、
前処理-コンパイル-アセンブル-リンク
アセンブリステップを完了する必要があります。アセンブリはアセンブリコードをマシンコードに変換することであり、生成されたファイルは.o
ファイルです。
gcc -c add.c
gcc -c sub.c
2.2静的ライブラリを作成する
静的ライブラリを作成することの本質は、いくつかの.oファイルをパッケージ化することです。
ar -ac libmymath.a add.o sub.o
静的ライブラリに含まれているファイルを表示するには、ar-tvを使用します。
2.3静的ライブラリの使用
3つのファイルadd.osub.olibmymath.aをslibフォルダーに配置します
1. -I
main.cをコンパイルおよびリンクするときに、ヘッダーファイルディレクトリを持ってくる必要があります。
gcc main.c -o main -I ./slib/
何かが足りないようです
2.-L
ライブラリファイルが配置されているディレクトリを移動するために使用します
gcc main.c -o main -I ./slib/ -L ./slib/
何かが足りないようです
3.-l
ライブラリの名前(libと.suffixの間の部分)を使用します
gcc main.c -o main -I ./slib/ -L ./slib/ -lmymath
この時点で、実行可能ファイルは正常に生成されます。
走る:
3.ダイナミックライブラリ
-
ダイナミックライブラリにリンクされた実行可能ファイルには、外部関数が存在するオブジェクトファイルのマシンコード全体ではなく、使用する関数エントリアドレスのテーブルのみが含まれます。
-
実行可能ファイルの実行が開始される前に、外部関数のマシンコードがオペレーティングシステムによってディスク上のダイナミックライブラリからメモリにコピーされます。これはダイナミックリンクと呼ばれるプロセスです。
-
ダイナミックライブラリは複数のプログラム間で共有できるため、ダイナミックリンクにより実行可能ファイルが小さくなり、ディスク容量が節約されます。オペレーティングシステムは仮想メモリメカニズムを使用して、物理メモリ内のダイナミックライブラリを、ライブラリを使用するすべてのプロセスで共有できるようにし、メモリとディスク領域を節約します。
3.1ダイナミックライブラリの作成
1.位置に依存しないコードを生成する
このダイナミックライブラリ自体は、共有領域にマップされたメモリのどの領域にもロードされません。また、どの場所でも、ライブラリ内のコードアドレスの相対的な変更に影響を与え、その結果、ライブラリの実行不可能なライブラリコードがマップされます。共有領域、および各プロセスがそれを使用します。同じコード、メモリの浪費なし
gcc -fPIC -c add.c sub.c
2.ダイナミックライブラリファイルを生成します
gcc -shared -o libmymath.so add.o sub.o
3.2ダイナミックライブラリを使用した実行可能ファイルの生成
gcc main.c -o main -I dlib/ -L dlib/ -lmymath
3.3実行中
実行main
でエラーが見つかりました、どうなりましたか?
编译
そこにいたときに、ヘッダーファイルディレクトリ、ライブラリファイルディレクトリ、ライブラリファイル名をすでに指定していませんでしたか?
ああ、コンパイル時に指定されていたのですが、現在は実行段階です。実行段階では、ライブラリファイルの場所が指定されていません。もちろん、見つかりません。
3つの回避策:
- コピー
libmymath.so
をシステム共有ライブラリパスにコピーします。通常、/usr/lib64
または/usr/lib
- dlibディレクトリをLD_LIBRARY_PATH環境変数に追加します
環境変数は次のとおりですLD_LIBRARY_PATH
。これは、システムがデフォルトでダイナミックライブラリファイルを検索するディレクトリを格納します
。環境変数のエクスポート:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/class101/linux/lesson18/dlib
- ldconfig構成
/etc/ld.so.conf.d
/etc/ld.so.conf.dディレクトリに任意に.confファイルを作成し、.confファイルにダイナミックライブラリディレクトリを書き込みます
echo "/root/class101/linux/lesson18/dlib" > /etc/ld.so.conf.d/test.conf
ldconfig
4.いくつかの詳細
詳細1
C言語がコンパイル時に-I-L-lなどのオプションを明示的に使用しないのはなぜですか?
1。ヘッダーファイルとライブラリファイルはデフォルトパスのgccによって検出されます2. gccが
Cコードをコンパイルする場合、デフォルトでlibcを検索する必要があります
これらのオプションも使用したくない場合はどうなりますか?
ヘッダーファイルライブラリファイルをデフォルトパスにコピーします->ライブラリのインストール
詳細2
gccのデフォルトの動的リンク。動的リンクがない場合は、静的リンクに移動します
Makefile
main: main.c
gcc -o $@ $^ -I ./dlib -L ./dlib -lmymath
.PHONY: clean
clean:
rm -f main