答えて
.soは、Windowsの.dllに似ています。 A .oはVisual Studioの.objとまったく同じです。
あなたがname.o
を生成cc name.c
で、あなたはそれをコンパイルするとname.c
#include <stdio.h>
#include <stdlib.h>
void print_name(const char * name)
{
printf("My name is %s\n", name);
}
それを呼び出す、あなたは以下のCソースファイルがあるとしましょう。 .oには、name.cで定義されたすべての関数と変数のコンパイル済みコードとデータ、および実際のコードと名前を関連付けたインデックスが含まれています。あなたはそのインデックスを見れば、(Linuxや他の多くのUnix上で利用可能)nm
ツールを使用すると、2つのエントリ気づく言う:
00000000 T print_name
U printf
をこれが何を意味するのか:二つのシンボル(関数や変数の名前があり、 .oに格納されているクラス、構造体、または任意の型の名前ではありません。最初にT
とマークされたの定義はname.o
です。 U
とマークされたもう1つは、の参照です。 print_name
のコードはここにありますが、printf
のコードでは見つかりません。あなたの実際のプログラムが実行されるときには、完全なプログラムまたは完全なライブラリにリンクされるために、他のオブジェクトファイルで、参照であるすべてのシンボルを見つけてその定義を検索する必要があります。したがって、オブジェクトファイルは、ソースファイルで見つかった定義をバイナリ形式に変換し、フルプログラムに組み込むことができます。
.oファイルを1つずつリンクすることはできますが、そうではありません。一般的には多くあり、実装の詳細です。あなたは、それらを全てよく関連するオブジェクトの束に集めて、よく知られた名前にしたいと思っています。これらのバンドルは、ライブラリと呼ばれ、スタティックとダイナミックの2つの形式があります。 (UNIXの場合)
スタティックライブラリはほとんど常にように.a
接尾辞(例としては、C数学ライブラリであるCコアライブラリ、libm.a
あるlibc.a
を含む)とされています。この例を続けると、スタティックライブラリをar rc libname.a name.o
で構築します。あなたは、それは主にそれですべての名前を見つけるインデックスを持つオブジェクトファイルの大きなテーブルで見ることができるように
name.o:
00000000 T print_name
U printf
:あなたはlibname.a
上nm
を実行する場合は、これを参照してくださいよ。オブジェクトファイルと同様に、.o
に定義されているシンボルとそれが参照するシンボルの両方が含まれています。 .o(例:date.o
〜)にリンクする場合は、上記のような別のエントリが表示されます。
実行可能ファイルに静的ライブラリをリンクすると、ライブラリ全体が実行可能ファイルに埋め込まれます。これは、すべての個々の.o
ファイルをリンクするのと同じです。あなたが想像しているように、これはあなたのプログラムを非常に大きくすることができます。特に、(最近のアプリケーションのように)多くのライブラリを使用している場合にはそうです。
動的又は共有ライブラリは.so
でサフィックスされます。静的なアナログのように、コンパイルされたすべてのコードを参照するオブジェクトファイルの大きなテーブルです。 cc -shared libname.so name.o
でビルドします。 nm
で見ることは静的ライブラリとはかなり異なっています。
00001498 a _DYNAMIC
00001574 a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
00001488 d __CTOR_END__
00001484 d __CTOR_LIST__
00001490 d __DTOR_END__
0000148c d __DTOR_LIST__
00000480 r __FRAME_END__
00001494 d __JCR_END__
00001494 d __JCR_LIST__
00001590 A __bss_start
w [email protected]@GLIBC_2.1.3
00000420 t __do_global_ctors_aux
00000360 t __do_global_dtors_aux
00001588 d __dso_handle
w __gmon_start__
000003f7 t __i686.get_pc_thunk.bx
00001590 A _edata
00001594 A _end
00000454 T _fini
000002f8 T _init
00001590 b completed.5843
000003c0 t frame_dummy
0000158c d p.5841
000003fc T print_name
U [email protected]@GLIBC_2.0
共有ライブラリが1つの非常に重要な方法で静的ライブラリと異なります:それはあなたの最終的な実行可能ファイル自体に埋め込まれません。私のシステムではそれがprint_name
とprintf
をしている2つだけそのうち約2ダースの記号が含まれています。実行可能ファイルには、リンク時ではなく実行時に解決される共有ライブラリへの参照が含まれています。これにはいくつかの利点があります。
- あなたの実行可能ファイルははるかに小さくなります。オブジェクトファイルを使用して明示的にリンクしたコードのみが含まれています。外部ライブラリは参照であり、そのコードはバイナリには入りません。
- 1つのライブラリのビットを複数の実行可能ファイルに共有することができます。
- バイナリ互換性に注意が必要な場合は、プログラムの実行間でライブラリ内のコードを更新することができます。プログラムは、変更することなく新しいライブラリを選択します。
いくつかの欠点があります。
- それは一緒にプログラムをリンクするために時間がかかります。共有ライブラリでは、実行可能ファイルが実行されるたびにこの時間の一部が遅延されます。
- このプロセスはより複雑です。共有ライブラリ内のすべての追加シンボルは、実行時にライブラリリンクを確立するために必要なインフラストラクチャの一部です。
- 異なるバージョンのライブラリ間で微妙な非互換性が発生する危険性があります。 Windowsではこれは "DLL hell"と呼ばれています。
(あなたが考えてみれば、これらの多くは、理由のプログラムを使用するか、または参照とポインタの代わりに、他のオブジェクトへのクラスの直接埋め込むオブジェクトを使用していないです。アナロジーはかなり直接的である。)
これは非常に細かいことですが、リンク処理が実際にどのように機能するかなど、私はずっとスキップしました。あなたがそれに従うことを願っています。明確化を求めない場合。
- 1. トラブルは、共有オブジェクトファイル
- 2. check_ntとcheck_nrpeは共有オブジェクトファイルにエラーを返します
- 3. 共有オブジェクトファイルを開くことができません
- 4. C++共有オブジェクトファイル内の完全な関数定義を見つける
- 5. NDKプロジェクトに事前構築された共有オブジェクトファイルを含む
- 6. テンプレートのC++オブジェクトファイル
- 7. バイナリコードのオブジェクトファイル
- 8. オブジェクトファイルの外観
- 9. TensorFlow(GPU)libcudart.so.7.5エラー - 共有オブジェクトファイルを開くことができません。
- 10. Lua liblua5.1.soは共有オブジェクトファイルを開くことができません
- 11. wkhtmltopdf - libfontconfig.so.1:共有オブジェクトファイルを開くことができません
- 12. メール-EXTオブジェクトファイルとして
- 13. Cオブジェクトファイルをアセンブリ言語オブジェクトファイルにリンクする方法は?
- 14. オブジェクトファイルとライブラリのシンボルの絡み合い
- 15. オブジェクトファイル内のシンボルテーブルと再配置テーブル
- 16. オブジェクトファイルは、DWARFデバッグ情報
- 17. gdbは "共有オブジェクトファイルを開くことができません"と言います
- 18. ノード-Javaエラー:libjvm.soは:共有オブジェクトファイルを開くことができません:そのようなファイルやディレクトリ
- 19. :libudev.so:共有オブジェクトファイルを開くことはできません:そのようなファイルまたはディレクトリ
- 20. はImportError:libcudart.so.7.0:共有オブジェクトファイルを開くことはできません:そのようなファイルまたはディレクトリ
- 21. libclntsh.so.11.1:CGIを実行中に共有オブジェクトファイルのpythonエラーを開くことができませんcx_Oracle
- 22. cuda_ndarray.cuをコンパイルできませんでした:libcublas.so.7.5:共有オブジェクトファイルを開くことができません
- 23. Herokuアプリがクラッシュする 'libruby.so.1.9:共有オブジェクトファイルを開くことができません'
- 24. 静的ライブラリ内のオブジェクトファイルの順序
- 25. Javaのオブジェクトファイルにリストのリストを保存
- 26. Linuxの実行可能ファイル内のオブジェクトファイル
- 27. Linuxでのオブジェクトファイルのアドレス指定Makefile
- 28. コンピュータ間でのオブジェクトファイルの互換性
- 29. nmakeオブジェクトファイルを別のディレクトリに置くMakefile
- 30. gccの中間ファイルからオブジェクトファイルをコンパイル
共有ライブラリはプラグインを実装する一般的な方法です。プラグインは、アプリケーション機能を変更せずに拡張する方法です。アプリケーションは、ライブラリへのパスをdlopen()に呼び出し、ライブラリ内の特定のシンボル(関数など)を見つけるためにdlsym()を呼び出して共有ライブラリをロードできます。ライブラリから機能を実行する関数へのアプリケーション呼び出し。 – dimba
読み込みとリンクの世界への素晴らしい紹介:) +1 – xtofl
素敵な説明:) +1 –