Windows system >> Windowsの知識 >  >> Linuxシステムチュートリアル >> Linuxチュートリアル >> Linuxの静的および動的ライブラリの解析

Linuxの静的および動的ライブラリの解析

  

ライブラリは動的および静的であり、動的は通常.soをサフィックスとして、staticを.aをサフィックスとして使用します。

例:libhello.so libhello.a同じシステムで異なるバージョンのライブラリを使用するには、プログラム接続のデフォルトのため、ライブラリファイル名の後にサフィックスにバージョン番号を追加できます。たとえば、libhello.so.1.0です。ファイル拡張子として.soを使用します。そのため、これらのライブラリを使用するためには、シンボリック接続を確立する方法を使用するのが一般的です。

$ ln -s libhello.so.1.0 libhello.so.1 //この場所でlibhello.so.1がどのように使用されているのかわかりませんか。 ?

$ ln -s libhello.so.1 libhello.so

1、ライブラリーを使用する

静的ライブラリーを使用する場合、コネクターはプログラムを見つけます。必要な関数が実行可能ファイルにコピーされ、このコピーが完了すると、接続が成功すると、静的ライブラリは不要になります。ただし、これは動的ライブラリの場合は当てはまりません。動的ライブラリは、プログラムの実行時にライブラリを最初にロードする必要があることを示すフラグを実行可能ファイルに残します。動的ライブラリーはスペースを節約するので、Linuxで接続するデフォルトの操作は、まず動的ライブラリーを接続することです。つまり、静的ライブラリーと動的ライブラリーが同時にある場合、指定されていない場合は動的ライブラリーと接続されます。

helloという名前のプログラム開発パッケージがあるとします。このパッケージは、静的ライブラリlibhello.a、動的ライブラリlibhello.so、ヘッダーファイルhello.hを提供し、ヘッダーファイルはsayhello()を提供します。 Br>

/*hello.h * /

void sayhello();

他にもドキュメントがあります。

これは典型的なプログラム開発パッケージの構造です。 Linuxのデフォルトは動的ライブラリ接続です。次のプログラムtestlib.cは、helloライブラリのsayhello()関数を使用します。

/*testlib.c*/

#include< stdio.h>

#include" hello.h"

int main(){sayhello(); return 0;}

$ gcc -c testlibをコンパイルするには、次のコマンドを使用します。 .c -o testlib.o

次のコマンドで接続します。$ gcc testlib.o -lhello -o testlib

接続時には注意してください。libhello.oとlibhello.aは存在しません。 /usr /libの下のライブラリ検索パスの下で、他の場所に-Lパラメータを追加する場合は、静的ライブラリと接続するのが面倒です。主にパラメータの問題です。あるいは上記の例:

$ gcc testlib.o -o testlib -WI、-Bstatic -lhello#-WI、-Bstaticは私のマシンには影響を及ぼさず、-static effectiveに変更されました

注:この特殊な "-WI、-Bstatic"パラメーターは、実際にはコネクターldに渡され、それが静的ライブラリーに接続されていることを示しますシステム内に静的ライブラリーしかない場合は、もちろん、このパラメーターは不要です。たとえば、複数のライブラリに接続し、各ライブラリが異なる方法で接続されている場合、上記のプログラムはlibhelloと静的に接続され、libbyeと動的に接続される必要があります。

$ gcc testlib.o -o testlib -WI -Bstatic -lhello -WI -Bdynamic -lbye

2.動的ライブラリのパスの問題実行可能ファイルが動的ライブラリをスムーズに見つけるためには、3つの方法があります。 >

(1)ライブラリを/usr /libおよび/libディレクトリにコピーします。

(2)環境変数LD_LIBRARY_PATHにライブラリのパスを追加します。たとえば、動的ライブラリlibhello.soは、bashを例として/home /ting /libディレクトリにあり、次のコマンドを使用します。

$ export LD_LIBRARY_PATH = $ LD_LIBRARY_PATH:/home /ting /lib

( 3)/etc/ld.so.confファイルを変更し、ライブラリのある場所のパスをファイルの末尾に追加し、ldconfigを実行して更新します。これにより、結合ディレクトリ内のすべてのライブラリファイルが表示されます。

3.ライブラリ内のシンボルの表示

ときどき、ライブラリに含まれる関数を確認する必要があるかもしれませんnmコマンドは、ライブラリに含まれるすべてのシンボルを出力することができます。ライブラリは静的でも動的でもかまいません。 nmでリストされた多くのシンボルがあります、一つはライブラリで呼ばれますが、ライブラリで定義されていない(他のライブラリサポートが必要であることを示す)、Uで表される3つの一般的なものがあります。これはTで最も一般的なもので、もう1つはいわゆる「弱い」シンボルで、ライブラリで定義されていますが、他のライブラリでも同じ名前のシンボルでカバーされることがあります。たとえば、開発者がprintf()が上記のhelloライブラリで定義されているかどうかを知りたいとします。

$ nm libhello.so |  Grep printf U

ここで、printf Uはシンボルprintfが参照されることを示しますが、関数内では定義されていませんhelloライブラリを通常使用するには、他のライブラリサポートが必要です。どのライブラリが利用可能です:

$ ldd hello libc.so.6 => /lib/libc.so.6(0× 400la000)/lib/ld-linux.so.2=>/lib/Ld-linux.so.2(0× 40000000)上記の結果から、printfが最終的に定義された場所を確認し続けることができます。興味があるのは続行できます。

4、build library

ソースコードはターゲットコードにコンパイルされます。次のコードを例として、上記で使用したhelloライブラリを生成します。

/* hello.c * /

#include< stdio.h>

void sayhello (){printf(' hello、world');}

gccを使用してこのファイルを編集します。編集時には、-gなどのデバッグコードを追加するための有効な編集パラメータを使用できます。 >

1. arコマンドを使用して静的ライブラリに接続するには、静的ライブラリに接続します。実際、arはarchive $ ar cqs libhello.a hello.o2の意味です。バージョンなので、通常はバージョン番号を指定します。

$ gcc -shared -Wl、-soname、libhello.so.1 -o libhello.so.1.0 hello.o

他の2つを追加シンボリックリンク:

$ ln -s libhello.so.1.0 libhello.so.1

$ ln -s libhello.so.1 libhello.so

Libhelloのダイナミックリンクライブラリが生成されます。最も重要なことは、gcc -sharedパラメータを渡して通常のexecutorではなく動的ライブラリにすることです。 -Wlは、次のパラメーターが-sonameであることを意味します。libhello.so.1は処理のためにコネクターldに直接渡されます。コネクターが探しているライブラリー内で名前を見つけると、コネクターは実行中の実際のファイル名の代わりに、リンク内のバイナリーにそのソナメを埋め込みます。プログラムの実行中、プログラムはライブラリのファイル名ではなく、sonameの名前のファイルを探します(つまり、sonameはライブラリの識別フラグです)。これは、主にシステム内に複数のバージョンのライブラリファイルを共存させることを目的としており、ライブラリファイルに名前を付けるときは同じlibxxxx.so.major.minorを使用するのが一般的です。マイナーはマイナーバージョン番号です。

Copyright © Windowsの知識 All Rights Reserved