共有オブジェクト (.so)、静的ライブラリ (.a)、DLL (.so) の違いは何ですか? 質問する

共有オブジェクト (.so)、静的ライブラリ (.a)、DLL (.so) の違いは何ですか? 質問する

私は Linux のライブラリに関するいくつかの議論に関わっており、いくつかのことを確認したいと思います。

私の理解では (間違っていたら訂正してください。後で投稿を編集します)、アプリケーションを構築するときにライブラリを使用する方法は 2 つあります。

  1. 静的ライブラリ(.a ファイル):リンク時に、ライブラリ全体のコピーが最終アプリケーションに配置され、ライブラリ内の関数が呼び出しアプリケーションで常に使用できるようになります。
  2. 共有オブジェクト (.so ファイル): リンク時に、オブジェクトは対応するヘッダー (.h) ファイルを介して API に対して検証されます。ライブラリは、実行時に必要になるまで実際には使用されません。

静的ライブラリの明らかな利点は、アプリケーション全体を自己完結的にできることです。一方、動的ライブラリの利点は、ベース アプリケーションを再コンパイルしなくても、「.so」ファイルを置き換えることができることです (つまり、セキュリティ バグのために更新する必要がある場合)。

共有オブジェクトとダイナミック リンク ライブラリ (DLL) はどちらも「.so」ファイルであるにもかかわらず、両者を区別する人がいると聞きました。Linux またはその他の POSIX 準拠 OS (MINIX、UNIX、QNX など) での C/C++ 開発では、共有オブジェクトと DLL に違いはありますか? これまでのところ、重要な違いの 1 つは、共有オブジェクトは実行時にのみ使用されるのに対し、DLL はアプリケーション内で dlopen() 呼び出しを使用して最初に開く必要があるということだそうです。

最後に、開発者の中には「共有アーカイブ」について言及している人もいますが、私の理解では、これも静的ライブラリですが、アプリケーションによって直接使用されることはありません。代わりに、他の静的ライブラリが「共有アーカイブ」にリンクして、共有アーカイブから一部 (すべてではありません) の関数/リソースをビルド中の静的ライブラリに取り込みます。

アップデート


これらの用語が私に提供された文脈では、それは Linux を学習しなければならなかった Windows 開発者のチームが使用した、事実上誤った用語でした。私はそれらを修正しようとしましたが、(誤った) 言語規範はそのまま残りました。

  1. 共有オブジェクト: プログラムの起動時に自動的にプログラムにリンクされ、スタンドアロン ファイルとして存在するライブラリ。ライブラリは、コンパイル時にリンク リストに含められます (つまり、LDOPTS+=-lmylibという名前のライブラリ ファイルの場合mylib.so)。ライブラリは、コンパイル時およびアプリケーションの起動時に存在している必要があります。
  2. 静的ライブラリ: 単一の (より大きな) アプリケーション用にビルド時に実際のプログラム自体にマージされるライブラリ。このアプリケーションには、プログラムがビルドされるときに自動的にプログラムにリンクされるライブラリ コードと、メイン プログラムとライブラリ自体の両方を含む最終バイナリが、単一のスタンドアロン バイナリ ファイルとして存在します。ライブラリは、コンパイル時にリンク リストに含められます (つまり、LDOPTS+=-lmylibという名前のライブラリ ファイルの場合mylib.a)。ライブラリは、コンパイル時に存在している必要があります。
  3. DLL: 基本的には共有オブジェクトと同じですが、コンパイル時にリンク リストに含まれるのではなく、ライブラリはdlopen()/dlsym()コマンドによってロードされるため、プログラムをコンパイルするためにビルド時にライブラリが存在している必要はありません。また、ライブラリはアプリケーションの起動時やコンパイル時に (必ずしも) 存在している必要はなくdlopen、 /dlsym呼び出しが行われた瞬間にのみ必要になります。
  4. 共有アーカイブ: 基本的には静的ライブラリと同じですが、"export-shared" フラグと " -fPIC" フラグを使用してコンパイルされます。ライブラリは、コンパイル時にリンク リストに含まれます (つまり、LDOPTS+=-lmylibSという名前のライブラリ ファイルの場合mylibS.a)。この 2 つの違いは、共有オブジェクトまたは DLL が共有アーカイブを独自のコードに静的にリンクし、共有オブジェクトの関数を DLL 内部で使用するだけでなく、他のプログラムで使用できるようにする必要がある場合に、この追加フラグが必要になることです。これは、誰かが静的ライブラリを提供し、それを SO として再パッケージ化する場合に役立ちます。ライブラリはコンパイル時に存在している必要があります。

追加アップデート

DLL「 」と「 」の区別は、shared library当時私が働いていた会社での(怠惰で不正確な)口語表現にすぎず(Windows 開発者は Linux 開発への移行を余儀なくされ、この用語が定着した)、上記の説明に従っていました。

さらに、S「共有アーカイブ」の場合、ライブラリ名の後に「 」リテラルが続くのは、その会社で使用されている慣例にすぎず、業界全体で使用されているものではありません。

ベストアンサー1

静的ライブラリ(.a)は、リンカーによって生成された最終的な実行可能ファイルに直接リンクできるライブラリです。このライブラリはリンカーに含まれており、実行可能ファイルが展開されるシステムにライブラリを配置する必要はありません。

共有ライブラリ(.so) は、最終的な実行可能ファイルにリンクされているが埋め込まれていないライブラリであるため、実行可能ファイルが起動されたときに読み込まれ、実行可能ファイルが展開されるシステムに存在する必要があります。

Windows 上のダイナミック リンク ライブラリ (.dll) はLinux上の共有ライブラリ (.so) に似ていますが、OS (Windows と Linux) に関連する 2 つの実装にはいくつかの違いがあります。

DLLでは、エクスポート関数と内部関数の 2 種類の関数を定義できます。エクスポート関数は、定義されている DLL 内だけでなく、他のモジュールからも呼び出されるように設計されています。内部関数は通常、定義されている DLL 内からのみ呼び出されるように設計されています。

Linux 上のSOライブラリでは、すべてのシンボルが照会プロセスで使用できるため、エクスポート可能なシンボルを示すための特別なエクスポート ステートメントは必要ありません。

おすすめ記事