LINXU動態庫應用
動態庫編寫:
ct.c 文件
#include<stdio.h>
void show()
{
printf(“hello library/n”);
}
gcc –fPIC –shared –o libct.so ct.c
(-fPIC -à 生成的文件爲可重定位的)
(-shared -à 生成動態鏈接庫 )
結果:生成libct.so 動態庫
調用動態庫
usect.c
#include<stdio.h>
int main ()
{
show();
}
gcc –o usect usect.c ./libct.so
結果:生成 usect 可執行文件
./usect
輸出:hello library
動態庫動態調用
dusect.c
#include<stdio.h>
#include<dlfnc.h>
int main ()
{
void *dp = NULL;
void (*fp)();
dp = dlopen(“./libct.so”, RTLD_LAZY);
if(dp == NULL)
{
printf(“load library error !/n”);
exit(1);
}
fp = dlsym(dp,”show”);
fp();
dlclose(dp);
return 0;
}
gcc –o dusect.out dusect.c –ldl
-ldl ---- -l<動態庫名> 要連接動態庫 ld(dlfnc.h要求的動態庫)
結果:生成 dusect.out 可執行文件
./dusect.out
輸出:hello library
如果dlopen的第一個參數是絕對路徑則直接打開
如果只是文件名則文件路徑搜索的順序:$LD_LIBRARY_PATH, /etc/ld.so.cache, /usr/lib , /lib
(能做 != 能做好 所以學習規範)
1、 命名約定
每個動態庫可由3個名字來命名分別爲:
(1)realname
lib + name + .so +.major_name.minor_name.patch_name
(例) libc.so.5.0.0
(2) soname
lib + name + .so +Library_name.major_name
例: libc.so.5
(3) linker name
lib + name + .so
例: libc.so
linkername 和 soname 都是符號鏈接文件
三者關係 :
linkername --à soname --àrealname
即:linkername 是 soname 的符號鏈接 soname 又是 realname 的符號鏈接
我們創建的動態庫首先要以realname來命名然後建立相應符號鏈接
編譯器以linkername來請求指定的鏈接庫
(爲什麼這樣做?這樣如果動態庫有版本更新時只需要替換原來的動態庫並重新設置soname指向的文件,應用程序不受到任何影響。因爲應用程序編譯時是用linkername 指定鏈接的動態庫的。)
(重新創建文章開頭的動態庫)
動態庫編寫:
ct.c 文件
#include<stdio.h>
void show()
{
printf(“hello library/n”);
}
gcc –fPIC –shared –o libct.so.1.0.0 ct.c
(-fPIC -à 生成的文件爲可重定位的)
(-shared -à 生成動態鏈接庫 )
結果:生成libct.so.1.0.0 動態庫
創建soname(符號鏈接)
ln –s libct.so.1.0.0 libct.so.1
創建linkername(符號鏈接)
ln –s libct.so.1 libct.so
usect.c
#include<stdio.h>
int main ()
{
show();
}
Gcc –o usect.out usect.c -L. -lct
結果:生成 usect.out 可執行文件
ldd usect.out
輸出:
。。。。。。
libct.so => ……..
libc.so.6 =>……..
。。。。。。
ldd命令列出來程序請求的動態庫(我們的usect.out 請求了libct.so動態庫)
./usect.out
輸出:(不能運行,找不到動態庫!!!!!)
程序怎樣尋找動態庫:程序在以下目錄裏依次查詢你要的動態庫。
$LD_LIBRARY_PATH, (環境變量)
/etc/ld.so.conf,
/usr/lib ,
/lib
每次都查找這麼多目錄影響性能,所以引入了/etc/ld.so.cache 文件來緩存查找路徑。
(系統每次啓動時都執行ldconfig 的程序,該程序是把/etc/ld.so.conf文件裏的路徑和, $LD_LIBRARY_PATH ,/usr/lib , /lib這些路徑信息加入到/etc/ld.so.cache裏。這樣每次查找動態庫時只需要查找/etc/ld.so.cache文件。)爲了讓系統能夠自動找到我的動態庫,只需要把我們的動態庫加入到/usr/lib 或 /lib 目錄裏 或者把我們動態庫所在的路徑信息加入到/etc/ld.so.conf 文件中 然後 啓動ldconfig 命令來刷新 /etc/ld.so.cache 緩存信息。
我的動態庫信息:
ls /hzp
libct.so.1.0.0 usect.out (我的文件都在 /hzp 目錄下)
現在把 /hzp 路徑信息加入 /etc/ld.so.conf
啓動 ldconfig
./usect.out
輸出: hello library !
開源軟件應遵守GNU 標準:當分發源代碼的時候,庫默認安裝在 /usr/local/lib,命令安裝
在/usr/local/bin。該標準還定義瞭如何重寫這些默認標準以及如何調用安裝程序。
Filesystem Hierarchy Standard(FHS) 規定:多數庫應安裝在 /usr/lib,啓動時需要的庫安裝在
/lib,非系統庫應安裝在 /usr/local/lib
GNU 標準是針對開發人員的,FHS 是針對發行者的。
來自:http://blog.csdn.net/huzhiping003/article/details/2914650