コンパイル時に実行可能ファイルに含まれるコードは、オブジェクト ファイル (.o ファイル) および静的にリンクされたライブラリ (.lib/.a ファイル) から取得できることを理解しています。これら2つの根本的および概念的な違いは何ですか? 「オブジェクト コード」と「静的にリンクされたライブラリ」の概念が異なるのはなぜですか? それぞれの長所と短所は何ですか? また、一方を他方とは対照的に使用する理由は何ですか? 静的にリンクされたライブラリをオブジェクト ファイルから作成できますか? 逆に、静的にリンクされたライブラリからオブジェクト ファイルを作成できますか?
2 に答える
オブジェクト ファイルは、コンパイルされているがリンクされていないコードです。ライブラリにはオブジェクト ファイルが含まれます。したがって、あなたの質問は、「オブジェクト ファイルしか使用できないのに、なぜ静的にリンクされたライブラリを使用するのですか?」ということになります。理由は次のとおりです。
それぞれが独自のシンボル テーブルを持つオブジェクトのコレクションとは異なり、ライブラリには、スイッチ を使用してライブラリ開発者によって呼び出されたときに作成される単一の統合されたシンボル テーブルがあります。そのアーカイブ内のすべてのオブジェクトに対して統一されたシンボル テーブルを作成する呼び出し。ar
s
s
ranlib
ranlib
シェルで実行すると、ヘルプ テキストの最初の行に次のように表示されます。
アーカイブへのアクセスを高速化するためのインデックスを生成します。
そして、一般的なranlib docsから:
このようなインデックスを持つアーカイブは、ライブラリへのリンクを高速化し、ライブラリ内のルーチンがアーカイブ内の配置に関係なく相互に呼び出すことを可能にします。T
FreeBSD ranlib docsも参照してください- 異なる言い回し、同じ考え: リンケージの速度。
ライブラリは、シンボルを解決するために検索できる、多くのオブジェクト ファイルを含む単なるファイルです。
したがって、通常、オブジェクトをリンクすると、すべてのオブジェクトが 1 つの実行可能ファイルに含まれます (ただし、一部の最適化リンカーは未使用のオブジェクトを破棄できます)。
ライブラリをリンカに渡すと、その中の各オブジェクト ファイルが検査され、未解決のシンボルを満たすために必要なファイルが取り込まれます (おそらく、すべてのシンボルが解決されるか、それ以上解決されなくなるまで、ライブラリが取り込まれ続けます)。 .
これは、リンカがより多くの作業を行えるように、多くのオブジェクトを 1 つのファイルに効率的にパッケージ化する方法にすぎません。必要なオブジェクトについて心配する必要はありません。
C ライブラリについて考えてみると、ソースを適切に分離した結果printf.o
、 、puts.o
、が発生する可能性があります。fopen.o
ユーザーが必要なすべてのオブジェクト ファイルを明示的にリストする必要はありません。そのため、すべてをパッケージ化してlibc.a
、その 1 つのファイルにリンクするだけでよいことをユーザーに伝えます。
静的にリンクされたビットはここでは関係ありません。オブジェクトが実行時に動的にロードされるのではなく、リンク時に実行可能ファイルに入る必要があることを決定するだけです。ここ で説明 します.