Linux動態庫、靜態庫載入基礎
靜態庫
在linux環境中, 使用ar命令建立靜態庫檔案.如下是命令的選項:
d -----從指定的靜態庫檔案中刪除檔案
m -----把檔案移動到指定的靜態庫檔案中
p -----把靜態庫檔案中指定的檔案輸出到標準輸出
q -----快速地把檔案追加到靜態庫檔案中
r -----把檔案插入到靜態庫檔案中
t -----顯示靜態庫檔案中檔案的列表
x -----從靜態庫檔案中提取檔案
還有多個修飾符修改以上基本選項,詳細請man ar 以下列出三個:
a -----把新的目標檔案(*.o)添加到靜態庫檔案中現有檔案之後
b -----***************************************之前
v -----使用詳細模式 ar 命令的命令列格式如下: ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files... eg: ar -crs hello.a hello.c
動態庫
1.建立共用庫
gcc -c error.c
gcc -c errorlog.c
gcc -shared -o libapue.so error.o errorlog.o
這樣就建立了共用庫!
2.編譯共用庫
假設共用庫位於目前的目錄(即跟程式檔案相同的目錄中)
gcc -o test -L. -lapue test.c
這樣就編譯出了不包含函數代碼可執行檔了,但是但你運行時會發現linux動態載入器打不到libapue.so檔案.
可以用ldd 命令查看可執行檔依賴什麼共用庫:
ldd test
如何才能讓動態載入器發現庫檔案呢?有兩種方法可以解決:
LD_LIBRARY_PATH 環境變數
/etc/ld.so.conf檔案
1.環境變數
export LD_LIBRARY_PATH="dir$LD_LIBRARY_PATH"
2.修改/etc/ld.so.conf檔案.位於/etc/ld.so.conf
一般應用程式的庫檔案不與系統庫檔案放在同一個目錄下,一般把應用程式的共用庫檔案放在/usr/local/lib下,建立一個屬於自己的目錄apue,然後把剛才libapue.so複製過去就行了
同時在/etc/ld.so.conf中新增一行:
/usr/local/lib/apue
執行個體分析:
test.c
#include
#include "print.h"
int main(void){
printf("Function : main/n");
print();
printf("out main/n");
return 0;
}
print.c
#include
#include
int print(void){
printf("Function : print/n");
printf("Hello world/n");
printf("out print/n");
return 0;
}
1 : 建立動態庫:
gcc -o libprint.so -fPIC -rdynamic -shared print.c
2 : 建立可執行檔
gcc -o test -I$(INC_PATH) -L$(LIB_PATH) -lprint test.c
3: 如果出現下列錯誤
./test: error while loading shared libraries: libprint.so: cannot open shared object file: No such file or directory
解決方案:
1: export LD_LIBRARY_PATH=DIR:$LD_LIBRARY_PATH
2: 修改檔案/etc/ld.so.config檔案,在末行加上你的庫檔案目錄,最後,ldconfig重新整理ld.so.cache檔案即可。可以用strings命令查看ld.so.cache是否重新整理:strings /etc/ld.so.cache | grep print
4: ldd命令查看動態串連庫
linux-gate.so.1 => (0xb7f0e000)
libprint.so => not found
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7d82000)
/lib/ld-linux.so.2 (0xb7ef4000)
5 : nm查看程式中有那些符號
049f18 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
080485cc R _IO_stdin_used
w _Jv_RegisterClasses
08049f08 d __CTOR_END__
08049f04 d __CTOR_LIST__
08049f10 D __DTOR_END__
08049f0c d __DTOR_LIST__
080485ec r __FRAME_END__
08049f14 d __JCR_END__
08049f14 d __JCR_LIST__
0804a018 A __bss_start
0804a010 D __data_start
08048580 t __do_global_ctors_aux
08048450 t __do_global_dtors_aux
0804a014 D __dso_handle
w __gmon_start__
0804857a T __i686.get_pc_thunk.bx
08049f04 d __init_array_end
08049f04 d __init_array_start
08048510 T __libc_csu_fini
08048520 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
0804a018 A _edata
0804a020 A _end
080485ac T _fini
080485c8 R _fp_hw
0804839c T _init
08048420 T _start
0804a018 b completed.6625
0804a010 W data_start
0804a01c b dtor_idx.6627
080484b0 t frame_dummy
080484d4 T main
U print
U puts@@GLIBC_2.0
6: strip取出程式中符號
7: strings查看可執行檔中的文本資訊
參考:http://www.kuqin.com/linux/20081103/25444.html
http://hi.baidu.com/li_zhongnan/blog/item/1d9bf3c2e13a9f32e4dd3b4f.html
本文來自ChinaUnix部落格,如果查看原文請點:http://blog.chinaunix.net/u3/94960/showart_1973740.html