歡迎您光臨本站 註冊首頁

和luster學習在Linux創建庫函數(4)

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  3.4. 創建一個共享函數庫

現在我們開始學習如何創建一個共享函數庫。其實創建一個共享函數庫非常容易。首先創建object文件,這個文件將加入通過gcc ?fPIC 參數命令加入到共享函數庫裡面。PIC的意思是「位置無關代碼」(Position Independent Code)。下面是一個標準的格式:

gcc -shared -Wl,-soname,your_soname -o library_name file_list library_list

下面再給一個例子,它創建兩個object文件(a.o和b.o),然後創建一個包含a.o和b.o的共享函數庫。例子中」-g」和「-Wall」參數不是必須的。

gcc -fPIC -g -c -Wall a.cgcc -fPIC -g -c -Wall b.cgcc -shared -Wl,-soname,liblusterstuff.so.1 -o liblusterstuff.so.1.0.1 a.o b.o -lc

下面是一些需要注意的地方:

· 不用使用-fomit-frame-pointer這個編譯參數除非你不得不這樣。雖然使用了這個參數獲得的函數庫仍然可以使用,但是這使得調試程序幾乎沒有用,無法跟蹤調試。

· 使用-fPIC來產生代碼,而不是-fpic。

· 某些情況下,使用gcc 來生成object文件,需要使用「-Wl,-export-dynamic」這個選項參數。通常,動態函數庫的符號表裡面包含了這些動態的對象的符號。這個選項在創建ELF格式的文件時候,會將所有的符號加入到動態符號表中。可以參考ld的幫助獲得更詳細的說明。


3.5. 安裝和使用共享函數庫

一旦你了一個共享函數庫,你還需要安裝它。其實簡單的方法就是拷貝你的庫文件到指定的標準的目錄(例如/usr/lib),然後運行ldconfig。
如果你沒有許可權去做這件事情,例如你不能修改/usr/lib目錄,那麼你就只好通過修改你的環境變數來實現這些函數庫的使用了。首先,你需要創建這些共享函數庫;然後,設置一些必須得符號鏈接,特別是從soname到真正的函數庫文件的符號鏈接,簡單的方法就是運行ldconfig:

ldconfig -n directory_with_shared_libraries

然後你就可以設置你的LD_LIBRARY_PATH這個環境變數,它是一個以逗號分隔的路徑的集合,這個可以用來指明共享函數庫的搜索路徑。例如,使用bash,就可以這樣來
啟動一個程序my_program:

LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH my_program

如果你需要的是重載部分函數,則你就需要創建一個包含需要重載的函數的object文件,然後設置LD_PRELOAD環境變數。

通常你可以很方便的升級你的函數庫,如果某個API改變了,創建庫的程序會改變soname。然而,如果一個函數升級了某個函數庫而保持了原來的soname,你可以強行將老版本的函數庫拷貝到某個位置,然後重新命名這個文件(例如使用原來的名字,然後後面加.orig後綴),然後創建一個小的「wrapper」腳本來設置這個庫函數和相關的東西。例如下面的例子:

#!/bin/sh export LD_LIBRARY_PATH=/usr/local/my_lib:$LD_LIBRARY_PATH exec /usr/bin/my_program.orig $*

我們可以通過運行ldd來看某個程序使用的共享函數庫。例如你可以看ls這個實用工具使用的函數庫:

ldd /bin/ls
libtermcap.so.2 => /lib/libtermcap.so.2 (0x4001c000)
libc.so.6 => /lib/libc.so.6 (0x40020000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

通常我么可以看到一個soname的列表,包括路徑。在所有的情況下,你都至少可以看到兩個庫:

· /lib/ld-linux.so.N(N是1或者更大,一般至少2)。這是這個用力載入其他所有的共享庫的庫。

· libc.so.N(N應該大於或者等於6)。這是C語言函數庫。


值得一提的是,不要在對你不信任的程序運行ldd命令。在ldd的manual裡面寫得很清楚,ldd是通過設置某些特殊的環境變數(例如,對於ELF對象,設置LD_TRACE_LOADED_OBJECTS),然後運行這個程序。這樣就有可能使得某地程序可能使得ldd來執行某些意想不到的代碼,而產生不安全的隱患。




[火星人 ] 和luster學習在Linux創建庫函數(4)已經有331次圍觀

http://coctec.com/docs/program/show-post-72218.html