linux 動態鏈結庫載入

2021-05-21 20:22:50 字數 1662 閱讀 2829

linux 動態鏈結

linux 中的應用程式以以下兩種方式之一鏈結到外部函式:要麼在構建時與靜態庫(lib*.a) 靜態地鏈結,並且將庫**包含在該應用程式的可執行檔案裡;要麼在執行時與共享庫(lib*.so) 動態地鏈結。通過動態鏈結裝入器,將動態庫對映進應用程式的可執行記憶體中。在啟動應用程式之前,動態鏈結裝入器將所需的共享目標庫對映到應用程式的記憶體,或者使用系統共享的目標並為應用程式解析所需的外部引用。現在應用程式就可以執行了。

main()

當使用 gcc 編譯 hello.c 時,就建立了乙個名為a.out的可執行檔案。通過使用 linux 命令ldd a.out(該命令列印出共享庫的相互依賴性),可以看出所需的共享庫是:

libc.so.6 => /lib/libc.so.6 (0x4001d000)

/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

使用相同的動態鏈結裝入器在應用程式執行之後將 dll 對映進應用程式的記憶體。通過使用 linux 動態裝入器例程,應用程式控制裝入哪乙個動態庫以及呼叫庫中的哪乙個函式,以執行裝入和鏈結以及返回所需入口點的位址。

回頁首

linux dll 函式

linux 提供 4 個庫函式(dlopen,dlerror,dlsymdlclose),乙個 include 檔案(dlfcn.h)以及兩個共享庫(靜態庫libdl.a和動態庫libdl.so),以支援動態鏈結裝入器。這些庫函式是:

回頁首

dll 示例:小的 c 程式和 dltest

動態鏈結裝入器示例程式是乙個小的 c 程式,該程式被設計用來練習 dl 例程。該程式基於每個人都編寫過的乙個 c 程式,它將「hello world」列印到控制台上。最初列印的訊息是「hello world」。該測試程式鏈結到再次列印該訊息的兩個函式上:第一次都用大寫字元,第二次都用小寫字元。

以下是該程式的概要:

使用絕對路徑「/home/dltest/lib庫.so」和選項 rtld_lazy,dlopen開啟 dll 的共享目標檔案並返回控制代碼。

選項 rtld_lazy 推遲解析 dll 的外部引用,直到 dll 被執行。

選項 rtld_now 在dlopen返回之前解析所有的外部引用。

dlsym返回入口點 函式的位址。

dlclose關閉到 lib.so 的控制代碼,並且從記憶體中取消 dll 對映。

dlopen使用基於環境變數 ld_library_path 的相對路徑查詢共享目標路徑,來開啟 dll 的共享目標檔案 lowercase.so,並且返回控制代碼。

注意,每次呼叫dlopendlsymdlclose之後,呼叫dlerror以獲取最後的錯誤資訊,並且列印該錯誤資訊字串。

動態鏈結庫延遲載入

開發的時候遇到乙個問題,有乙個可執行程式需要依賴另外乙個目錄的動態庫,但是對這個dll介面的引用採用的是靜態依賴的方式。解決不難,可以通過loadlibrary動態載入,然後呼叫其介面。但是這用就沒法方便的通過靜態以依賴的方式方便的呼叫其介面了。探索後發現vs支援延遲繫結。就是呼叫的時候可以通過靜態...

手動載入動態鏈結庫

手動載入動態鏈結庫常用於外掛程式式架構開發 dlfcn.h標頭檔案提供了api 以下我們給出常用的4個函式 open the shared object file and map it in return a handle that can be passed to dlsym to get sym...

linux動態鏈結庫的載入順序

1.編譯程式時用到動態庫,該從那些地方查詢,按照怎麼樣的順序查詢?2.執行程式時需要動態庫,該從那些地方查詢,按照怎麼樣的順序查詢?1.gcc 編譯時引數 l指定的路徑 2.環境變數 library path 3.系統預設庫位置 lib usr lib 1.gcc 編譯時指定的執行時庫路徑 wl,r...