GNU/Linux >> Linux の 問題 >  >> Linux

動的リンクのしくみ、その使用法、および dylib を作成する方法と理由

主な違いは、静的にリンクされたライブラリをアプリに含めることです。これらは、アプリをビルドするときにリンクされます。動的ライブラリは実行時にリンクされるため、アプリに含める必要はありません。最近では、動的ライブラリを使用して、すべてのコンピューターに多数の動的ライブラリを配置することでアプリのサイズを縮小しています。

動的ライブラリを使用すると、ユーザーはクライアント アプリを再構築せずにライブラリを更新することもできます。アプリで使用するライブラリにバグが見つかり、それが静的にリンクされている場合は、アプリを再構築してすべてのユーザーに再発行する必要があります。動的にリンクされたライブラリにバグが見つかった場合、すべてのユーザーはライブラリを更新するだけでよく、アプリを更新する必要はありません。


<ブロック引用>

C++ プログラムがコンパイルされるとき。 C++ ライブラリの関数とコード (ライブラリのコードなど) への参照が必要です。

libdyno.so という架空の共有ライブラリがあるとします。 .最終的に objdump を使用して内部を覗くことができます または nm .

objdump --syms libdyno.so

共有ライブラリを使用して、システムで今日これを行うことができます。 objdump MAC では gobjdump と呼ばれます binutils で brew が付属しています パッケージ。これを Mac で試してみてください...

gobjdump --syms /usr/lib/libz.dylib

シンボルが共有オブジェクトに含まれていることがわかります。 link の場合 共有オブジェクトでは、通常、次のようなものを使用します

g++ -Wall -g -pedantic -ldyno DynoLib_main.cpp -o dyno_main

-ldyno に注意してください そのコマンドで。これは、コンパイラ (実際にはリンカー ld) に libdyno.so という共有オブジェクト ファイルを探すように指示しています。 通常それらを探す場所。そのオブジェクトが見つかると、必要なシンボルを見つけることができます。開発者が -l を指定して動的ライブラリをロードするように要求したため、循環依存関係はありません

<ブロック引用>

動的ライブラリをいつ、どのように使用しますか?どうやって作るの?標準の .cpp ファイルからそのようなファイルを生成するために使用される特定のコンパイル コマンドは何ですか

DynoLib.cpp という名前のファイルを作成します

#include "DynoLib.h"
DynamicLib::DynamicLib() {}
int DynamicLib::square(int a) {
  return a * a;
}

DynoLib.h という名前のファイルを作成します

#ifndef DYNOLIB_H
#define DYNOLIB_H
class DynamicLib {
  public:
  DynamicLib();
  int square(int a); 
};
#endif

以下のようにコンパイルして共有ライブラリにします。これは Linux 固有のものです...

g++ -Wall -g -pedantic -shared -std=c++11 DynoLib.cpp -o libdyno.so

以前に与えたコマンドを使用して、このオブジェクトを調べることができます。

objdump --syms libdyno.so

libdyno.so にリンクする DynoLib_main.cpp というファイルを作成します。 定義したばかりの関数を使用します。

#include "DynoLib.h"    
#include <iostream>     
using namespace std;
int main(void) {
  DynamicLib *lib = new DynamicLib();
  std::cout << "Square " << lib->square(1729) << std::endl;
  return 1;
}

次のようにコンパイルします

g++ -Wall -g -pedantic -L. -ldyno DynoLib_main.cpp -o dyno_main
./dyno_main
Square 2989441

nm を使用してメイン バイナリを確認することもできます。 .以下では、文字列 square を持つものがあるかどうかを確認しています その中に、つまり libdyno.so から必要なシンボルがあります 私のバイナリで何らかの方法で参照されています。

nm dyno_runner |grep square
U _ZN10DynamicLib6squareEi

答えはイエスです。大文字の U は未定義を意味しますが、これは以前に作成した DynamicLib クラスの square メソッドのシンボル名です。奇妙に見える名前は、独自のトピックである名前マングリングによるものです。

<ブロック引用>

通常の.o ファイルの場合と同じように静的にリンクするファイルと、動的にリンクする必要があるファイルをどのように確認できますか?

知る必要はありません。リンクしたいものを指定し、コンパイラー (およびリンカーなど) に作業を任せます。 -l に注意してください フラグはライブラリと -L に名前を付けます どこを見るかを指示します。コンパイラがここで物事を見つける方法についてのまともな記事があります

gcc リンケージ オプション -L:動的ライブラリへのパスを指定する別の方法

または man ld を見てください .

<ブロック引用>

-L フラグと -l フラグは何のためのものですか?たとえば、コマンド ラインで -lusb フラグを指定するとはどういう意味ですか?

上記のリンクを参照してください。これは man ld からです ..

<ブロック引用>

-L searchdir

ld がアーカイブ ライブラリと ld 制御スクリプトを検索するパスのリストにパス searchdir を追加します。このオプションは何度でも使用できます。ディレクトリは、コマンド ラインで指定された順序で検索されます。コマンド ラインで指定されたディレクトリは、デフォルト ディレクトリの前に検索されます。オプションが表示される順序に関係なく、すべての -L オプションがすべての -l オプションに適用されます。 -L オプションは、-T オプションが指定されていない限り、ld がリンカースクリプトを検索する方法に影響しません。`

ここにたどり着いた場合は、リンカー、つまり ld について学ぶことで利益が得られます。これは重要な役割を果たしており、多くの混乱の原因となっています。なぜなら、ほとんどの人はコンパイラを扱い始めて compiler == linker と考えるからです。 これは正しくありません。


Linux
  1. Ansibleの静的および動的ホストインベントリを管理する方法

  2. キャッシュとしてのRedis:その仕組みと使用理由

  3. データが重要である理由とその保護方法

  1. TAMとは何ですか?なぜあなたはTAMになりたいのですか?

  2. cpを取得する理由:Linuxでのディレクトリエラーの省略と解決方法

  3. 共有ライブラリのロードとRAMの使用?

  1. すべてのRhythmbox設定とライブラリ情報をリセットする方法は?

  2. コンテンツキュレーションとは何ですか?どのように行う必要がありますか?

  3. Linux 共有ライブラリの紹介 (共有ライブラリの作成方法)