歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux動態鏈接庫的應用學習

Linux動態鏈接庫的應用學習

日期:2017/2/28 14:37:20   编辑:Linux教程

Linux系統下分為兩種類型的函數庫:

1. 靜態庫
靜態庫的鏈接工作是在程序編譯階段完成的。
每個需要調用該靜態庫的程序中都有一份該庫的拷貝,
所以靜態庫在程序中的絕對位置在編譯階段就確定下來了;
由於多個程序中同時有多份靜態庫的拷貝,所以增大了程序的大小。

2. 動態鏈接庫
動態鏈接庫在程序編譯階段不會被拷貝到程序中。
它是程序在運行階段需要調用庫時才去將函數庫鏈接到可執行程序中的。
由於它是動態加載的,所以它在程序中的絕對位置是不確定的;
但是函數庫內部的各個函數之間的相對位置是在編譯期間確定下來的。
動態鏈接庫需要操作系統的支持,幸運的是現在的操作系統基本上都支持動態鏈接庫。

由於是程序運行時根據需要實時的載入庫,
所以如果函數庫找不到或者函數庫中缺少某個庫函數都會造成程序執行錯誤。
對於動態鏈接庫來講,這樣的錯誤只能在程序運行時才能被發現。
如果是靜態庫,則這些錯誤可以在程序編譯階段被提早發現。

使用動態鏈接庫的好處有:
1. 真正的實現了函數庫和程序的分離,庫函數提供者不必關心程序的其它部分。
他們只需要提供可用的動態函數庫即可。

2. 讓程序的升級變得簡單
如果動態鏈接庫有改動,不必去編譯整個可執行程序,讓程序開發變得方便簡單。
用戶只需要編譯這個動態鏈接庫,然後將其copy到動態鏈接庫原本的存放位置,重新運行程序即可。

接下來就具體學習如何應用動態鏈接庫的這個特性,以方便程序開發。
具體步驟如下:
1. 確定所使用的函數庫所在的系統的位置,可以使用find命令進行查找
sh-3.2# find / -name "libtest.so"

2. 將編譯好的.so文件copy到對應的步驟1找到的位置,
sh-3.2# mount -o sync -t vfat /dev/sda1 /mnt/
其中參數-o帶sync參數用來指定該分區是以sync方式進行寫操作;
參數-t用來指定待mount的分區的文件系統類型。

3. 重新運行這個程序,這時程序就是加載了新的動態鏈接庫運行了。

4. 使用ldd命令可以用來查看程序依賴於哪些動態鏈接庫
sh-# ldd ./test_main
libc.so.6 => /lib/libc.so.6 (0x40113000)
/lib/ld-linux.so.3 (0x40022000)
sh-#
關於ldd可以參考下面這篇文章, http://www.linuxidc.com/Linux/2014-01/94718.htm

如果程序很龐大,如何確認某個模塊或某個函數是屬於哪一個動態鏈接庫(在一個很大系的統中是有可能的)?
假定函數位於某個動態鏈接庫中,則可以使用objdump將動態鏈接庫進行反匯編,然後在結果中查找指定的函數,
sh-3.2# objdump -d ./libtest.so | grep function

使用readelf或nm都無法准確的定位函數處於哪個.so文件中,
sh-3.2# readelf -s ./libtest.so | grep function
sh-3.2# nm ./libtest.so | grep function
原因是這個符號既會在函數所在的庫中查到,同時在調用這個函數的庫中也能查到。

Copyright © Linux教程網 All Rights Reserved