1. linux中的庫
庫用於將相似函式打包在乙個單元中。然後這些單元就可為其他開發人員所共享,並因此有了模組化程式設計這種說法。在linux下常見的庫檔案,就是*.so檔案。linux中絕大多數.so檔案都存放在/lib、/usr/lib/(見linux目錄結構),對於64位和32位共存的系統,32位的動態庫可能會放在/lib32.
2.動態庫和靜態庫
linux支援兩種型別的庫,每一種庫都有各自的優缺點。靜態庫是在編譯階段隨使用者程式一塊進行編譯。動態庫則不同,它是在載入應用程式時被載入的,而且它與應用程式是在執行時繫結的。
(1)靜態鏈結——可執行程式包含了其所需的全部庫函式;所有庫函式都連線到程式中。 這類程式是完整的,其執行不需要外部庫的支援。 靜態鏈結程式的優點之一是其安裝之前不需要做環境準備工作 。
(2)動態鏈結——可執行程式要小得多;這類程式執行時需要外部共享 函式庫的支援,因此好像並不完整。除了程式體小之外,動態鏈結允許程式包指定必須的庫,而不必將庫裝入程式包內。動態鏈結技術還允許多個執行中的程式共享乙個庫,這樣就不會出現同一**的多份拷貝共佔記憶體的情況了。由於這些原因,當前多數程式採用動態鏈結技術。
在linux中的庫有靜態庫和動態庫兩種,其中動態庫又分為動態鏈結庫和動態載入庫兩種。
3.動態鏈結庫和動態載入庫
gnu/linux中共享庫的使用主要有兩種方式,一種方式和.a的靜態庫類似由編譯器來控制,其實質和二進位制程式一樣都是由系統中的載入器(ld-linux.so)載入;另一種是寫在**中,由我們自己的**來控制.
(1)動態鏈結庫
您可以動態地將程式和共享庫鏈結並讓 linux 在執行時載入庫(如果它已經在記憶體中了,則無需再載入)。
(2)動態載入庫
使用動態載入的過程,這樣程式可以有選擇地呼叫庫中的函式。使用動態載入過程,程式可以先載入乙個特定的庫(已載入則不必),然後呼叫該庫中的某一特定函式。這是構建支援外掛程式的應用程式的乙個普遍的方法。這種方法需要使用linux提供的動態載入dl api來控制載入庫以及使用庫中的函式。dl提供的api如下表所示:
表 1. dl api
函式描述
dlopen
使物件檔案可被程式訪問
dlsym
獲取執行了dlopen
函式的物件檔案中的符號的位址
dlerror
返回上一次出現錯誤的字串錯誤
dlclose
關閉目標檔案
如下是使用dl api的例程:
#include #include #include #define max_string 80
void invoke_method( char *lib, char *method, float argument )
/* resolve the symbol (method) from the object */
func = dlsym( dl_handle, method );
error = dlerror();
if (error != null)
/* call the resolved method and print the result */
printf(" %f\n", (*func)(argument) );
/* close the object */
dlclose( dl_handle );
return;
}int main( int argc, char *argv )
}
4.靜態鏈結庫的定義和使用方式
(1)靜態鏈結庫的定義
通過編譯的預處理、編譯階段生成的目標檔案就可以作為靜態鏈結庫。
(2)靜態鏈結庫的使用
有兩種方式,一種是g++ -o main main.cpp ./libullib.a,直接將libullib.a庫鏈結到二進位制程式main中;另一種是g++ -o main main.cpp -l./ -lullib,這種和動態鏈結庫的使用方式一樣,但是生成靜態鏈結庫和動態鏈結庫的方式是不一樣的。
5.共享庫的定義和使用方式,
(1)共享庫的定義
生成共享庫和生成靜態庫類似,只是加上了 -shared 和 -fpic,將輸出命名改為.so,這樣生成的執行程式即為共享庫。
g++ -shared -fpic -o libx.so libx.cpp
(2)共享庫的使用
兩種方式,一種是g++ -o main main.cpp -l./ -lx,通過gcc/g++的-l和-l引入。一種是程式中顯示控制。
6.linux中庫的查詢順序
(1)linux gcc編譯以及鏈結時對依賴的庫的查詢順序
1.gcc編譯、鏈結命令中的-l選項
2.gcc的環境變數的library_path(多個路徑用冒號分割)
3.gcc預設動態庫目錄:/lib:/usr/lib:usr/lib64:/usr/local/lib
(2)執行二進位制檔案時的對依賴的共享庫的查詢順序
1.編譯目標**時指定的動態庫搜尋路徑:用選項-wl,rpath和include指定的動態庫的搜尋路徑,比如gcc -wl,-rpath,include -l. -ldltest hello.c,在執行檔案時會搜尋路徑`./include`
2.環境變數ld_library_path(多個路徑用冒號分割)
3.由ldconfig工具構建的/etc/ld.so.cache快取檔案中查詢
4.gcc預設動態庫目錄:/lib:/usr/lib:usr/lib64:/usr/local/lib等
7.共享庫的載入
對於依賴共享庫的可執行檔案在真正執行前,實際上它的很多外部符號還處於無效狀態,還未與實際的so檔案聯絡起來,因此還有乙個動態鏈結過程。作業系統會首先載入動態鏈結器ld.so(/lib/ld-linux.so.2),載入完這個so後,系統就會把控制權交給它,然後它會進行一些初始化操作,根據當前環境引數對可執行檔案進行動態鏈結工作。動態鏈結器會尋找所需要的.so檔案並進行裝載,然後進行符號查詢及重定位。如果找不到所需要的符號定義就會產生「undefined symbol」錯誤。
8.庫檔案生成,修改工具ar
ar命令可以用來建立、修改庫,也可以從庫中提出單個模組。庫是一單獨的檔案,裡面包含了按照特定的結構組織起來的其它的一些檔案(稱做此庫檔案的member)。原始檔案的內容、模式、時間戳、屬主、組等屬性都保留在庫檔案中。
ar工具的詳細使用可以參見
linux下靜態庫與動態庫的建立與使用
目錄 一 庫的概念 二 庫的知識 三 靜態庫 1 特點 2 建立 3 使用 4 小結 三 共享庫 1 特點 2 建立 3 使用 4 如何找到共享庫 5 小結 1 庫是乙個原始碼編譯後的二進位制檔案,包含的 可被程式使用 2 庫的種類 標準c庫 資料庫 執行緒庫.4 庫的存放路徑 lib usr li...
Linux下共享庫的製作與使用
linux下共享庫的製作與使用 還是使用上面的例子程式 生成共享庫 動態鏈結庫 gcc fpic shared o libstr.so strlen.c strnlen.c fpic 使輸出的物件模組是按照可重定位位址方式生成的。shared 指定把對應的原始檔生成對應的動態鏈結庫檔案 libstr...
Linux下共享庫的製作與使用
生成共享庫 動態鏈結庫 gcc fpic shared o libstr.so strlen.c strnlen.c fpic 使輸出的物件模組是按照可重定位位址方式生成的。shared 指定把對應的原始檔生成對應的動態鏈結庫檔案 libstr.so 檔案。動態庫的使用 動態庫的分為隱式呼叫和顯式呼...