2016-04-11 6 views
1

スタックオーバーフローに関するいくつかの記事を読んで、オンラインでダイナミックリンクを読むことができました。そして、これは私がこれらすべての読み取り値から奪ったものです。ダイナミックリンクの仕組み、その使い方、そしてなぜあなたがdylibを作成するのか

ダイナミックリンクは、システムの仮想メモリを最大限に活用するために採用された最適化手法です。あるプロセスがそのページを他のプロセスと共有することができます。たとえば、libC++はすべてのC++プログラムにリンクする必要がありますが、実行可能ファイルをすべてのプロセスにコピーする代わりに、共有仮想ページを介して多くのプロセスと動的にリンクすることができます。

C++のプログラムがコンパイルされている場合ただし、これは、次の質問

  1. に私をリードしています。 C++ライブラリの関数とコードへの参照が必要です(例えば、<スレッド>ライブラリのコード)。コンパイラはどのようにこれらの参照を持つ実行可能ファイルを作成しますか?これは、コンパイラとオペレーティングシステムの間に循環依存を生じませんか?コンパイラは実行可能ファイル内の動的ライブラリへの参照を作成する必要があるためです。
  2. どのように、いつ動的ライブラリを使用しますか?どうやって作るの?このようなファイルを標準の.cppファイルから生成するために使用される特定のコンパイルコマンドは、
  3. です。通常、ライブラリをインストールすると、.aのファイルと.dylib(Macの場合)ファイルのlib/ディレクトリがあります。 .oファイルの場合と同じように、どのファイルを静的にリンクするのか、どのファイルを動的にリンクするのかを知るにはどうすればよいですか?私は.dylibファイルが動的ライブラリであると仮定しています。どのコンパイラフラグを使用してこれらにリンクしますか?
  4. -Lフラグと-lフラグは何ですか?たとえば、コマンドラインで-lusbフラグを指定するとはどういう意味ですか?

この質問のように思われる場合は、すぐにあまりにも多くのことを尋ねています。教えてください。私は完全にこの質問を複数のものに分割することで大丈夫だろう。 1つの質問に対する答えが別の質問につながるように感じるので、私は一緒に尋ねます。

+1

ここで必要なものを見つけることができます... http://stackoverflow.com/questions/496664/c-dynamic-shared-library-on-linux – Harry

答えて

2

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

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

objdump --syms libdyno.so 

今日、システム上で共有ライブラリを使用してこれを行うことができます。 MAC上のobjdumpgobjdumpと呼ばれ、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ファイルから

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

DynoLib.cpp

というファイルを作成し、ファイルの発信者DynoLibを作成します。 h

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

次のように共有ライブラリとしてコンパイルします。これは

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

あなたは今、私が与えたコマンドを使用して、このオブジェクトを検査することができます...のLinux固有である以前すなわち

objdump --syms 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メソッドのシンボル名です。奇妙な名前は、それが自分の話題である名前のmanglingに起因しています。

はどのようにしているものとする静的に私と同じようにリンクすることを知っています定期的なものを動的にリンクされたことになっている の.oファイルと?

あなたは知る必要はありません。あなたはリンクしたいものを指定し、コンパイラ(とリンカなど)に作業をさせます。 -lフラグはライブラリ名を示し、-Lはどこに表示するかを示します。コンパイラはここの事

gcc Linkage option -L: Alternative ways how to specify the path to the dynamic library

それともman ldを見てを見つける方法についてのまともな書き込みアップがあります。

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

上記のリンクを参照してください。これは、ldは アーカイブライブラリとLD制御スクリプトを検索するパスのリストに

-Lをsearchdir

追加パスをsearchdirを... man ldからです。このオプションは、 の回数だけ使用できます。ディレクトリは、コマンド行で が指定されている順に検索されます。 コマンドラインで指定されたディレクトリは、デフォルトディレクトリの前に検索されます。すべて-L オプションは、オプションが表示される順序に関係なく、すべての-lオプションに適用されます。 -Tオプションはspecified.`

でない限り、あなたがここに得ることができた場合は、-Lオプションは、リンカ スクリプトのどのLDの検索には影響しません。それは、リンカすなわちLDについて学ぶために配当金を支払います。それは重要な仕事をしており、多くの人々がコンパイラを扱うことから始まり、compiler == linkerと考えているので、これは真実ではないので、混乱の大部分です。

1

主な違いは、アプリケーションに静的リンクライブラリを含めることです。それらはあなたのアプリを構築するときにリンクされています。ダイナミックライブラリは実行時にリンクされるため、アプリにそれらを含める必要はありません。最近では、ダイナミックライブラリを使用して、全員のコンピュータに多数のダイナミックライブラリを持たせることで、アプリケーションのサイズを縮小しています。

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

+0

ありがとうございます!それは私がオンラインで読んだ概念的な説明です!私は、これらの共有ライブラリがどのように動作するか、コンパイラがどのように起動時にOSを呼び出すコードを生成するのか、これを実現する方法について、さらに詳しく調べました。とにかくおかげで! – Curious

+0

コンパイラは、システム上のローダーによって使用され、必要に応じて編集される(アドレスを設定する)オブジェクトファイルを生成します。それらをどのように構築するかは、環境によって異なります。たとえば、XCodeでは、プロジェクトを作成するときに、プロジェクトの作成時にライブラリを構築するように指定できます。 –

+0

しかし、それはコンパイラをオペレーティングシステムに依存させ、循環依存につながりますか? – Curious

関連する問題