linux 共享庫基本使用

<SCRIPT src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type=text/javascript> </SCRIPT>

1 創建和使用靜態庫
   靜態庫是指編譯連接時,把庫文件的代碼全部加入到可執行文件中,所以生成的文件較大, 但運行時,就不再需要庫文件了。動態庫正好相反,在編譯連接時,沒有把庫文件的代碼加入到可執行文件中,所以生成的文件較小,但運行時,仍需要加載庫文件

  .a是靜態庫文件,可以用ar 命令生成。
  .so是動態庫文件,編譯時加上指定的選項即可生成,具體選項看相應的系統文檔了。。。。

創建一個靜態庫是相當簡單的。通常使用 ar 程序把一些目標文件(.o)組合在一起,
成爲一個單獨的庫,然後運行 ranlib,以給庫加入一些索引信息。

如:
靜態庫生成  #gcc -shared -o libmyfunction.so myfunction.o
動態庫生成  #ar -r -olibmyfunction.a myfunction.o

2 創建和使用共享庫
特殊的編譯和連接選項
-D_REENTRANT         使得預處理器符號 _REENTRANT 被定義,這個符號激活一些宏特性。
-fPIC                選項產生位置獨立的代碼。由於庫是在運行的時候被調入,因此這個
                     選項是必需的,因爲在編譯的時候,裝入內存的地址還不知道。如果
                     不使用這個選項,庫文件可能不會正確運行。
-shared              選項告訴編譯器產生共享庫代碼。
-Wl,-soname          -Wl 告訴編譯器將後面的參數傳遞到連接器。而 -soname 指定了
                     共享庫的 soname。

    # 可以把庫文件拷貝到 /etc/ld.so.conf 中列舉出的任何目錄中,並以
root 身份運行 ldconfig;或者
    # 運行 export LD_LIBRARY_PATH='pwd',它把當前路徑加到庫搜索路徑中去。

1.7.9  使用高級共享庫特性
1. ldd 工具
ldd 用來顯示執行文件需要哪些共享庫, 共享庫裝載管理器在哪裏找到了需要的共享庫.

2. soname

共享庫的一個非常重要的,也是非常難的概念是 soname——簡寫共享目標名(short for shared object name)。這是一個爲共享庫(.so)

文件而內嵌在控制數據中的名字。如前面提到的,每一個程序都有一個需要使用的庫的清單。這個清單的內容是一系列庫的 soname,如同 ldd

顯示的那樣,共享庫裝載器必須找到這個清單。
soname 的關鍵功能是它提供了兼容性的標準。當要升級系統中的一個庫時,並且新庫的 soname 和老的庫的 soname 一樣,用舊庫連接生成的

程序,使用新的庫依然能正常運行。這個特性使得在 Linux 下,升級使用共享庫的程序和定位錯誤變得十分容易。
在 Linux 中,應用程序通過使用 soname,來指定所希望庫的版本。庫作者也可以通過保留或者改變 soname 來聲明,哪些版本是相互兼容的

,這使得程序員擺脫了共享庫版本衝突問題的困擾。
查看/usr/local/lib 目錄,分析 MiniGUI 的共享庫文件之間的關係

3. 共享庫裝載器

當程序被調用的時候,Linux 共享庫裝載器(也被稱爲動態連接器)也自動被調用。它的作用是保證程序所需要的所有適當版本的庫都被調入

內存。共享庫裝載器名字是 ld.so 或者是 ld-linux.so,這取決於 Linux libc 的版本,它必須使用一點外部交互,才能完成自己的工作。然

而它接受在環境變量和配置文件中的配置信息。
文件 /etc/ld.so.conf 定義了標準系統庫的路徑。共享庫裝載器把它作爲搜索路徑。爲了改變這個設置,必須以 root 身份運行 ldconfig 工

具。這將更新 /etc/ls.so.cache 文件,這個文件其實是裝載器內部使用的文件之一。

可以使用許多環境變量控制共享庫裝載器的操作(表1-4+)。

                        表 1-4+ 共享庫裝載器環境變量
變量                       含義
LD_AOUT_LIBRARY_PATH       除了不使用 a.out 二進制格式外,與 LD_LIBRARY_PATH 相同。
LD_AOUT_PRELOAD            除了不使用 a.out 二進制格式外,與 LD_PRELOAD 相同。
LD_KEEPDIR                 只適用於 a.out 庫;忽略由它們指定的目錄。
LD_LIBRARY_PATH            將其他目錄加入庫搜索路徑。它的內容應該是由冒號
                           分隔的目錄列表,與可執行文件的 PATH 變量具有相同的格式。
                           如果調用設置用戶 ID 或者進程 ID 的程序,該變量被忽略。
LD_NOWARN                  只適用於 a.out 庫;當改變版本號是,發出警告信息。
LD_PRELOAD                 首先裝入用戶定義的庫,使得它們有機會覆蓋或者重新定義標準庫。
                           使用空格分開多個入口。對於設置用戶 ID 或者進程 ID 的程序,
                           只有被標記過的庫才被首先裝入。在 /etc/ld.so.perload 中指定
                           了全局版本號,該文件不遵守這個限制。

5.ldconfig
  庫安裝到系統以後, 爲了讓動態鏈接庫爲系統所認識及共享, 就需要運行ldconfig.ldconfig命令的用途, 主要是在默認搜尋目錄(/lib

和/usr/lib)以及動態庫配置文件/etc/ld.so.conf內所列的目錄下, 搜索出可共享的動態鏈接庫(格式如lib*.so*), 進而創建出動態裝入程序

(ld.so)所需的連接和緩存文件.緩存文件默認爲/etc/ld.so.cache, 此文件保存已排好序的動態鏈接庫名字列表, ldconfig通常在系統啓動時

運行, 而當用戶安裝了一個新的動態鏈接庫時,就需要手工運行這個命令.

     (1)命令格式
 ldconfig [選項] [libs]

     (2)主要選項
 -v或--verbose ldconfig將顯示正在掃描的目錄、搜索到的動態鏈接庫, 以及它所創建的連接的名字.

 -f CONF 指定動態鏈接庫的配置文件爲CONF, 系統默認爲/etc/ld.so.conf.

 -C CACHE 指定生成的緩存文件爲CACHE, 系統默認的是/etc/ld.so.cache,文件存放已排好序的可共享的動態鏈接庫的列表.

 -p或--print-cache 讓ldconfig打印出當前緩存文件所保存的所有共享庫的名字.

 -r ROOT 改變應用程序的根目錄爲ROOT.

 -n ldconfig僅掃描命令行指定的目錄, 不掃描默認目錄(/lib、/usr/lib),也不掃描配置文件/etc/ld.so.conf所列的目錄.

 運行沒有選項的ldconfig命令時, 用於更新高速緩衝文件.這個命令主要用於高速緩衝DNS服務器(Caching DNS Server).高速緩衝DNS服務器的

原理是提供查詢的歷史記錄, 並且利用這些記錄來提高查詢的效率.

 當某個查詢是第一次被髮送到高速緩衝DNS服務器時, 高速緩衝DNS服務器就將此查詢的整個過程記錄下來, 在一定的時期內用它來回答所有相

同的查詢, 從而減少整個DNS系統的負擔並且提高查詢速度.

6. 使用 dlopen

    另外一個強大的庫函數是 dlopen()。該函數將打開一個新庫,並把它裝入內存。該函數主要用來加載庫中的符號,這些符號在編譯的時候

是不知道的。比如 Apache Web 服務器利用這個函數在運行過程中加載模塊,這爲它提供了額外的能力。一個配置文件控制了加載模塊的過程

。這種機制使得在系統中添加或者刪除一個模塊時,都不需要重新編譯了。
    可以在自己的程序中使用 dlopen()。dlopen() 在 dlfcn.h 中定義,並在 dl 庫中實現。它需要兩個參數:一個文件名和一個標誌。文件

名可以是我們學習過的庫中的 soname。標誌指明是否立刻計算庫的依賴性。如果設置爲 RTLD_NOW 的話,則立刻計算;如果設置的是

RTLD_LAZY,則在需要的時候才計算。另外,可以指定 RTLD_GLOBAL,它使得那些在以後才加載的庫可以獲得其中的符號。
    當庫被裝入後,可以把 dlopen() 返回的句柄作爲給 dlsym() 的第一個參數,以獲得符號在庫中的地址。使用這個地址,就可以獲得庫中

特定函數的指針,並且調用裝載庫中的相應函數。

<SCRIPT src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type=text/javascript> </SCRIPT>
發佈了8 篇原創文章 · 獲贊 2 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章