Linux:静的関数ライブラリ(.a)と動的関数ライブラリ(.so)


Linux:静的関数ライブラリ(.a)と動的関数ライブラリ(.so)
関数ライブラリは2種類あります.
1.     :             ,    ,      .a2.     :            ( )   ,      .so

静的関数ライブラリ:
Linuxの一般的なコマンドはtarで、指定した「パッケージ」にファイルをパッケージ化するために使用されます.
Javaでよく使われるコマンドはjarで、いくつかの.classのバイトコードファイルを指定した「ファイルパッケージ」(jarパッケージ)にパッケージします.
静的関数ライブラリ.aはファイルパッケージであり、中には.oのファイル(.aは.oの集合であり、多くの.oが結合して.aを構成している)が含まれていることが理解できます.
コマンドarを使用して.aファイルを生成できます.注:arはarchiverの略です.
静的関数ライブラリの一般的な利点は、次のとおりです.
1.ターゲットプログラムを生成する場合、対応する静的ライブラリを指定するだけでよく、静的ライブラリの関連ソースファイルを再コンパイルする必要がなく、時間を節約することができる.
2.他の人に何かを使いたいが、相手に自分のソースコードを知られたくない場合は、静的ライブラリを作って彼に使うことができます.他の人はいくつかの.oファイルを手に入れて、元のコードを手に入れることができません.
例:
説明:基本演算を含むmymath.aの静的ライブラリを構築します.
mymath.h
#ifndef _MYMATH_H
#define _MYMATH_H
int add(int, int);
int sub(int, int);
int mul(int, int);
int dev(int, int);
#endif

mymath.C
#include "mymath.h"

int add(int a, int b)
{ return a + b; }
int sub(int a, int b)
{ return a - b; }
int mul(int a, int b)
{ return a * b; }
int dev(int a, int b)
{ return a / b; }

main.C
#include 
#include "mymath.h"

using namespace std;

int main()
{
    cout<10, 22)<return 0;
}

コンパイルmymath.Cはmymath.o
[jiang@eb50 43]$ g++ -c mymath.C

mymath.oファイルのみを含む静的ライブラリを生成
[jiang@eb50 43]$ ar rcs mymath.a mymath.o

コンパイル生成先ファイルmain
[jiang@eb50 43]$ g++ -o main main.C mymath.a
[jiang@eb50 43]$ ll
   32
-rwxrwxr-x 1 jiang jiang 8912 10-16 19:00 main
-rw-rw-r-- 1 jiang jiang  115 10-16 18:43 main.C
-rw-rw-r-- 1 jiang jiang 1840 10-16 19:00 mymath.a
-rw-rw-r-- 1 jiang jiang  181 10-16 18:58 mymath.C
-rw-rw-r-- 1 jiang jiang  119 10-16 18:34 mymath.h
-rw-rw-r-- 1 jiang jiang 1656 10-16 19:00 mymath.o
[jiang@eb50 43]$ ./main
32

arのオプション(rcs)については、(manar)を参照してください.
r:Insert the files member… into archive (with replacement). c:Create the archive. s:Write an object-file index into the archive, or update an existing one, even if no other change is made to the archive.
詳細については、manマニュアルも参照してください.
動的関数ライブラリ:
.so動関数ライブラリは、プログラム起動時にロードするもよいし、プログラム中でdlopenなどの操作を用いてプログラム実行中に動的にロードするもよい.
ダイナミックリンクライブラリは、通常のプログラムと比較するmain関数がなく、一連の関数の実現である.
動的関数ライブラリの名前:
通常、mymathのダイナミックライブラリの名前は次のとおりです.
libmymath.so[   ]

lib+動的苦命+.so+バージョン情報
/usr/libでは、次のような多くのソフトリンクが表示されます.
lrwxrwxrwx   1 root root       26 2013-03-13 libssl.so -> ../../lib/libssl.so.0.9.8e

私たちは逆さまに来ました.
ライブラリsslを使用する場合は、リンク時に-lsslを追加する必要があります.
リンクは-lsslを見て、libssl.soというライブラリファイル(またはソフトリンク)を探すことを知っています.
sslライブラリはどこですか?通常コンパイル時刻は-Lによって検索の経路が決定される.
libssl.soが見つかったのはソフトリンクで、実際には別のライブラリ(..//../lib/libssl.so.0.9.8 e)を指しています.
見えますか?libssl.soが指すファイル名はlibssl.so.0.9.8 eである.
次の形式を比較します.
0.9.8 eはバージョン情報です.
すなわち、libxxx.soというソフトリンクをよく使用し、実際にバージョン情報付きの実際のライブラリファイルを指します.
ダイナミックライブラリの作成方法
例:
説明:libmymath.soを構築し、基本演算を含む.
mymath.h
#ifndef _MYMATH_H
#define _MYMATH_H
int add(int, int);
int sub(int, int);
int mul(int, int);
int dev(int, int);
#endif

mymath.C
#include "mymath.h"

int add(int a, int b)
{ return a + b; }
int sub(int a, int b)
{ return a - b; }
int mul(int a, int b)
{ return a * b; }
int dev(int a, int b)
{ return a / b; }

main.C
#include 
#include "mymath.h"

using namespace std;

int main()
{
    cout<10, 12)<return 0;
}

ダイナミックライブラリを生成するには
[jiang@eb50 43]$ g++ -fPIC -g -c mymath.C
[jiang@eb50 43]$ g++ -shared -g mymath.o -o libmymath.so.1
[jiang@eb50 43]$ ln -s libmymath.so.1 $PWD/libmymath.so
[jiang@eb50 43]$ ll
   32
lrwxrwxrwx 1 jiang jiang   14 10-16 19:40 libmymath.so -> libmymath.so.1
-rwxrwxr-x 1 jiang jiang 8231 10-16 19:40 libmymath.so.1
-rw-rw-r-- 1 jiang jiang  115 10-16 19:39 main.C
-rw-rw-r-- 1 jiang jiang  181 10-16 18:58 mymath.C
-rw-rw-r-- 1 jiang jiang  119 10-16 18:34 mymath.h
-rw-rw-r-- 1 jiang jiang 4856 10-16 19:40 mymath.o

ダイナミックライブラリの使用(コンパイル時):
[jiang@eb50 43]$ g++ -o main main.C -L $PWD -lmymath

ターゲット・プログラムの実行:
[jiang@eb50 43]$ ll
   44
lrwxrwxrwx 1 jiang jiang   14 10-16 19:40 libmymath.so -> libmymath.so.1
-rwxrwxr-x 1 jiang jiang 8231 10-16 19:40 libmymath.so.1
-rwxrwxr-x 1 jiang jiang 8804 10-16 19:42 main
-rw-rw-r-- 1 jiang jiang  115 10-16 19:39 main.C
-rw-rw-r-- 1 jiang jiang  181 10-16 18:58 mymath.C
-rw-rw-r-- 1 jiang jiang  119 10-16 18:34 mymath.h
-rw-rw-r-- 1 jiang jiang 4856 10-16 19:40 mymath.o
[jiang@eb50 43]$ ./main
./main: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory

エラーが発生しました.
まず最後の間違いを一時的に置いて、ここにはいくつか注意しなければならない点があります.
1.    .o      -fPIC  ,  :Position Independent Code;
2.   .o     .so   -shared3.ln -s       ,    ,      2    libmymath.so     ,            ;
4.-L-l       ;
 :  -lxxx-L       libxxx.so    ,        ,           ;

はい、最後の運転で発生した問題を解決します.
まずlddを使用してmainという実行可能ファイルがどのダイナミックライブラリと関係があるかを確認できます.
[jiang@eb50 43]$ ldd main
    linux-vdso.so.1 =>  (0x00007fff077fd000)
    libmymath.so => not found
    libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003a53600000)
    libm.so.6 => /lib64/libm.so.6 (0x0000003a41800000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003a51a00000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003a41000000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003a40800000)

(ldd prints the shared libraries required by each program or shared library specified on the command line.)
libmymath.soが見つからなかったのはなぜですか?
ldd/実行時は、-L(実際にはこの-Lはありません)から検索されませんでした.
-Lはgcc/g++のコンパイル時のオプションであり、どのディレクトリからダイナミックライブラリファイルを検索するかを示す.
実行時刻のライブラリロード(検索)現在のshellの環境変数LD_LIBRARY_PATH決定;
[jiang@eb50 43]$ export LD_LIBRARY_PATH=.
[jiang@eb50 43]$ ldd main
    linux-vdso.so.1 =>  (0x00007fff912a6000)
    libmymath.so => ./libmymath.so (0x00002b0ad452b000)
    libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003a53600000)
    libm.so.6 => /lib64/libm.so.6 (0x0000003a41800000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003a51a00000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003a41000000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003a40800000)
[jiang@eb50 43]$ ./main
22

もちろん、LD_にあげることができます.LIBRARY_PATHは絶対経路であり、「相対経路」ではない.
もう一つのダイナミックライブラリの使用方法はdlopenシリーズの関数を使って操作することであり、これは後で紹介する.
参照先:
1.http://blog.csdn.net/ithomer/article/details/7346146 2.http://www.cnblogs.com/Anker/p/3527677.html