[解決済み] オブジェクトファイルとライブラリファイル、その理由は?
質問
コンパイルの基本は理解しています。 ソースファイルはオブジェクトファイルにコンパイルされ、リンカーはそれを実行ファイルにリンクします。 これらのオブジェクトファイルは、定義を含むソースファイルから構成されています。
そこで質問です。
- なぜ、ライブラリのために別の実装をするのですか? .a .lib, .dll...
- 私はおそらく勘違いしているのですが、.o ファイル自体がライブラリと同じようなものであるように思えます。 はライブラリと同じようなものだと思うのですが?
- ある特定の宣言(.h)の .o 実装を誰かが与えてくれて、それを置き換えて 宣言 (.h) の .o の実装を提供し、それを置き換えてリンクさせれば 同じ機能を実行する実行ファイルになります。 異なるオペレーションを使用する実行可能ファイルになりますか?
どのように解決するのですか?
歴史的に、オブジェクトファイルは実行ファイルに完全にリンクされるか、まったくリンクされないかのどちらかです (現在では 関数レベル リンク または プログラム全体の最適化 が一般的になりつつあります)、そのため、オブジェクトファイルの1つの関数が使用されると、実行ファイルはそれらのすべてを受け取ります。
実行ファイルを小さく保ち、デッドコードをなくすために、標準ライブラリは多くの小さなオブジェクトファイル (通常、数百のオーダー) に分割されています。何百もの小さなファイルを持つことは、効率上の理由から非常に望ましくありません。多くのファイルを開くのは非効率的ですし、どのファイルにも多少のスラック(ファイルの末尾にある未使用のディスクスペース)があります。このため、オブジェクトファイルはライブラリにまとめられ、圧縮されていないZIPファイルのようなものになります。リンク時には、ライブラリ全体が読み込まれ、リンカがライブラリを読み始めたときにすでに未解決とわかっていたシンボルを解決するそのライブラリからのすべてのオブジェクトファイル、またはそれらによって必要とされるオブジェクトファイルが出力に含まれます。これは、依存関係を再帰的に解決するために、ライブラリ全体が一度にメモリ上に存在する必要があることを意味していると思われる。メモリ量がかなり限られていたため、リンカーは一度に 1 つのライブラリしか読み込まず、リンカーのコマンド ラインで後から言及されたライブラリは、コマンド ラインで先に言及されたライブラリの関数を使用することができません。
パフォーマンスを向上させるために(特にフロッピーディスクのような遅いメディアからライブラリ全体をロードするのは時間がかかります)、ライブラリにはしばしば
インデックス
を含んでおり、リンカにどのオブジェクトファイルがどのシンボルを提供するかを知らせます。インデックスを作成するツールは
ranlib
やライブラリ管理ツール (Borland の
tlib
にはインデックスを生成するスイッチがあります)。インデックスがあるとすぐに、すべてのオブジェクト ファイルがディスク キャッシュにあり、ディスク キャッシュからのファイルの読み込みが無料であっても、ライブラリは単一のオブジェクト ファイルよりも確実に効率的にリンクされます。
あなたが完全に正しいのは、私が
.o
または
.a
ファイルを作成し、ヘッダーファイルはそのままに、関数の処理内容(または処理方法)を変更します。これを利用するのが
LPGL-license
を使用するプログラムの作者に要求されるものです。
LGPL-licensed
を使用するプログラムの作者に対して、 そのライブラリをパッチされた、改良された、あるいは代替の実装で置き換える可能性を ユーザに提供することを要求しています。ユーザーに必要な自由を与えるには、アプリケーションのオブジェクトファイル (場合によってはライブラリファイルとしてグループ化されたもの) を出荷すれば十分です。
GPL
).
2つのライブラリ(またはオブジェクトファイル)のセットが、同じヘッダファイルで正常に使用できる場合、それらは次のように言われます。 ABI 互換 といいます。ここで、ABI とは アプリケーション バイナリ インターフェイス . これは、単に2組のライブラリ(またはオブジェクトファイル)にそれぞれのヘッダを付属させ、この特定のライブラリのヘッダを使えばそれぞれのライブラリを使えることを保証するよりも狭いものです。これは、次のように呼ばれるでしょう。 API の互換性 ここで、API とは アプリケーション・プログラム・インターフェース . この違いの例として、次の3つのヘッダーファイルを見てください。
ファイル1:
typedef struct {
int a;
int __undocumented_member;
int b;
} magic_data;
magic_data* calculate(int);
ファイル2
struct __tag_magic_data {
int a;
int __padding;
int b;
};
typedef __tag_magic_data magic_data;
magic_data* calculate(const int);
ファイル3.
typedef struct {
int a;
int b;
int c;
} magic_data;
magic_data* do_calculate(int, void*);
#define calculate(x) do_calculate(x, 0)
最初の2つのファイルは同一ではありませんが、(私が期待する限り)"1定義ルール"に違反しない交換可能な定義を提供しているので、ファイル1をヘッダーファイルとして提供するライブラリは、ファイル2をヘッダーファイルとして同様に使用することができます。一方、ファイル 3 はプログラマに非常によく似たインターフェイスを提供しますが(ライブラリの作者がライブラリのユーザに約束することはすべて同じかもしれません)、ファイル 3 でコンパイルしたコードは、ファイル 1 またはファイル 2 で使用するように設計されたライブラリとはリンクできず、ファイル 3 用に設計したライブラリはエクスポートしないでしょうから
calculate
をエクスポートせず
do_calculate
. また、構造体のメンバーレイアウトが異なるため、File 3 ではなく File 1 や File 2 を使用すると、b に正しくアクセスできません。File 1 と File 2 を提供するライブラリは ABI 互換ですが,3 つのライブラリとも API 互換です(c とより高機能な関数である
do_calculate
はその API にカウントされないと仮定しています)。
動的ライブラリ(.dll、.so)については完全に異なります。複数の(アプリケーション)プログラムを同時にロードできるシステムで登場し始めました(DOSではそうではありませんが、Windowsではそうなっています)。ライブラリ関数の同じ実装を何度もメモリ上に置くのは無駄なので、一度だけロードして複数のアプリケーションで利用するのである。ダイナミックライブラリの場合、参照する関数のコードは実行ファイルに含まれず、ダイナミックライブラリ内の関数への参照だけが含まれる(Windows NE/PEでは、どのDLLがどの関数を提供しなければならないかが指定されている。Unixの.soファイルでは、関数名とライブラリのセットのみが指定されています)。オペレーティングシステムには ローダー と呼ばれる ダイナミックリンカー は、これらの参照を解決し、プログラムが開始された時点でまだメモリ内にない場合は動的ライブラリをロードします。
関連
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み】Enterキーを押して続行する
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない