[解決済み】共有オブジェクト(.so)、静的ライブラリ(.a)、DLL(.so)の違い?)
質問
Linuxのライブラリに関する議論に参加したことがあり、いくつか確認したいことがあります。
私の理解では(間違っていたら訂正してください、後で投稿を編集します)、アプリケーションを構築する際にライブラリを使用する方法は2つあると思います。
- 静的ライブラリ(.aファイル)。リンク時に、ライブラリ全体のコピーが最終的なアプリケーションに入れられ、ライブラリ内の関数が呼び出し側のアプリケーションで常に利用できるようになります。
- 共有オブジェクト(.soファイル)。リンク時、オブジェクトは対応するヘッダー(.h)ファイルを介してそのAPIに対して検証されるだけです。ライブラリは、実行時に必要になるまで、実際には使用されません。
静的ライブラリの明らかな利点は、アプリケーション全体を自己完結させることができることです。一方、動的ライブラリの利点は、ベースアプリケーションを再コンパイルすることなく、".so" ファイルを交換できる(つまり、セキュリティバグにより更新が必要になった場合)ことです。
共有オブジェクトとダイナミックリンクライブラリ(DLL)は同じquot;.so"ファイルですが、区別している人がいると聞いたことがありますが、どうでしょうか?Linuxやその他のPOSIX準拠のOS(MINIX、UNIX、QNXなど)でC/C++を開発する場合、共有オブジェクトとDLLに区別はあるのでしょうか?DLLはアプリケーション内でdlopen()コールを使って最初に開かなければならないのに対して、共有オブジェクトは実行時に使用されるだけだということが(今のところ)一つの重要な違いだと聞いています。
私の理解では、共有アーカイブも静的ライブラリですが、アプリケーションによって直接使用されることはありません。その代わり、他の静的ライブラリは共有アーカイブに対してリンクし、共有アーカイブの関数やリソースの一部(すべてではありません)をビルド中の静的ライブラリに取り込みます。
皆さん、よろしくお願いします。
更新情報
この用語が私に提供された文脈では、Linuxを学ばなければならないWindowsの開発者チームが使った、事実上の誤った用語でした。私はそれらを訂正しようとしましたが、(間違った)言語規範が定着してしまいました。
-
Shared Objectの略。プログラム起動時に自動的にリンクされ、スタンドアロンファイルとして存在するライブラリ。このライブラリは、コンパイル時にリンクリストに含まれます(例.
LDOPTS+=-lmylib
という名前のライブラリファイルに対してmylib.so
). ライブラリは、コンパイル時およびアプリケーションの起動時に存在する必要があります。 -
スタティック・ライブラリ。アプリケーションコードとライブラリコードを含む単一の(より大きな)アプリケーションのビルド時に実際のプログラム自体にマージされるライブラリで、プログラムビルド時にプログラムに自動的にリンクされ、メインプログラムとライブラリ自体の両方を含む最終バイナリは単一のスタンドアロンバイナリファイルとして存在します。ライブラリは、コンパイル時にリンクリストに含まれます(すなわち、:
LDOPTS+=-lmylib
という名前のライブラリファイルに対してmylib.a
). コンパイル時にライブラリが存在する必要があります。 -
DLL:基本的には共有オブジェクトと同じですが、コンパイル時にリンクリストに含まれるのではなく、ライブラリは
dlopen()
/dlsym()
コマンドを使用することで、プログラムのコンパイル時にライブラリが存在する必要はありません。 また、アプリケーションの起動時やコンパイル時にライブラリが存在する必要は(必ずしも)ない を実行した瞬間に必要なだけである。dlopen
/dlsym
の呼び出しが行われます。 -
共有アーカイブ。基本的にはスタティック・ライブラリと同じですが、"export-shared"と".Shared;でコンパイルされたものです。
-fPIC
フラグ。このライブラリは、コンパイル時にリンクリストに含まれます (例:LDOPTS+=-lmylibS
という名前のライブラリファイルに対してmylibS.a
). この 2 つの違いは、共有オブジェクトまたは DLL が共有アーカイブを自身のコードに静的にリンクし、共有オブジェクト内の関数を DLL 内部で使用するだけでなく、他のプログラムでも使用できるようにしたい場合に、この追加フラグが必要になることです。これは、誰かが静的ライブラリを提供してくれて、それをSOとして再パッケージ化したい場合に便利です。 コンパイル時にライブラリが存在する必要があります。
追加更新
"の区別。
DLL
と「"
shared library
"は、当時私が働いていた会社での(いい加減で不正確な)口語表現(Windows開発者がLinux開発に移行させられ、この言葉が定着した)で、上記の記述に準拠しているだけである。
さらに、末尾の"
S
共有アーカイブの場合、ライブラリ名の後に「"」というリテラルを付けるのは、その会社での慣習であり、業界一般ではありません。
解決方法は?
WindowsではDLLと呼ばれ、UNIXシステムでは共有オブジェクトと呼ばれ、ダイナミック・リンク・ライブラリという一般用語が両方をカバーしています(UNIXでは.soをオープンする関数も
dlopen()
ダイナミックライブラリ」の後)。
確かにアプリケーションの起動時にのみリンクされますが、ヘッダーファイルとの照合という考え方は正しくありません。ヘッダーファイルは、ライブラリを使用するコードをコンパイルするために必要なプロトタイプを定義していますが、リンク時にリンカーはライブラリ自体の内部を見て、必要な関数が実際に存在することを確認します。リンカはリンク時に関数本体をどこかで見つけなければならず、さもなければエラーになります。あなたの指摘するように、ライブラリ自体はプログラムがコンパイルされた後に変更されている可能性がありますから、実行時にも同じことが行われます。ABIが変更されると、古いバージョンに対してコンパイルされた既存のプログラムが壊れてしまうからです。
スタティック・ライブラリは、プロジェクトのコンパイルの一部として自分で構築するのと同じように、コンパイラから直接オブジェクト・ファイルをバンドルしているだけなので、まったく同じ方法でリンカに取り込まれて供給され、まったく同じ方法で未使用のビットが削除されるのです。
関連
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] const int*、const int * const、int const *の違いは何ですか?
-
[解決済み] 私的相続、公的相続、保護相続の違いについて
-
[解決済み] ++iとi++の違いは何ですか?
-
[解決済み] g++とgccの違いは何ですか?
-
[解決済み] mallocとcallocの違い?
-
[解決済み] スタティック・ライブラリとシェアード・ライブラリの違い?
-
[解決済み】スタティックリンクとダイナミックリンクの比較
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み] テスト
-
[解決済み】C-stringを使用すると警告が表示される。"ローカル変数に関連するスタックメモリのアドレスが返される"
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照