linux動態鏈結

2021-07-05 12:36:41 字數 1934 閱讀 9265

在程式中總會用到各式各樣的庫,有兩種使用方式:靜態鏈結庫和動態鏈結庫,在windows下分別對應.lib檔案和.dll檔案,使用靜態庫時需要包含對應的標頭檔案並引用lib檔案,使用動態庫則需要手動通過函式載入dll中的函式。

linux下使用方法則有所不同,linux下.a檔案.so檔案分別對應靜態和動態鏈結庫。

ar rcs libmylib.a mylib.o 生成.a靜態庫

gcc -o hello main.c -l. -lmylib 生成可執行檔案hello;gcc會在mylib之前自動新增lib,即找檔案libmylib.a

./hello 執行

可以發現即使刪除libmylib.a檔案,hello也可以執行。

gcc -fpic -shared -o libmylib.so mylib.c 生成.so動態庫

gcc -o hello main.c -l. -lmylib 生成可執行檔案hello;gcc會在mylib之前自動新增lib,即找檔案libmylib.so

./hello 執行

./hello: error while loading shared libraries: libmylib.so: cannot open shared object file: no such file or directory

按照第一種方法解決,

gcc -o hello main.c -l. -lmylib-wl,-rpath=.引數-wl,-rpath=. 指定當前路徑為動態庫搜尋路徑

./hello 可執行

按照第二種方法解決,

export ld_library_path=.

./hello 可執行

使用命令readelf -d hello可見其搜尋路徑 library rpath: [.]

dynamic section at offset 0x7b0 contains 22 entries:

tag type name/value

0x0000000000000001 (needed) shared

library: [libmyhello.so]

0x0000000000000001 (needed) shared

library: [libc.so.6]

0x000000000000000f (rpath) library rpath: [.]

0x000000000000000c (init) 0x400490

0x000000000000000d (fini) 0x4006b8

0x000000006ffffef5 (gnu_hash) 0x400260

第三種方法,

第四種方法,

把libmylib.so檔案拷貝到/lib中

第四種方法,

把libmylib.so檔案拷貝到/lib中

第五種方法,

把libmylib.so檔案拷貝到/usr/lib中

在實際使用中第一和第二種方法最經常被採納,但是使用變數ld_library_path時要注意,一旦ld_library_path變數被設定之後,該變數生效範圍內的所有程式執行時都會先查詢該變數所指定的搜尋目錄,這樣勢必會造成一些浪費。

參考

Linux動態鏈結器

我開始以為動態鏈結器 ld linux.so.x 是linux 核心的一部分,其實這種想法是錯誤的。分析完elf可執行檔案在核心中載入啟動的原始碼後,可以參考博主的這兩篇部落格 linux載入啟動可執行程式的過程 一 核心空間載入elf的過程 linux載入啟動可執行程式的過程 二 直譯器完成動態鏈...

Linux動態鏈結之三 動態鏈結相關結構

無論是靜態鏈結還是動態鏈結,初始都是作業系統讀取可執行檔案的file header,以檢查檔案格式 操作許可權等屬性,然後根據段表獲取各個 segment 的vma虛擬裝載位置 檔案位址和操作屬性rwxp等,再根據相似屬性原則相連原則完成裝載,而後將控制權交給檔案頭結構中e entry入口位址 el...

Linux下動態鏈結與靜態鏈結

一 首先我們來說一下庫的基礎概念 在windows平台和linux平台下都大量存在著庫。本質上來說庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。由於windows和linux的本質不同,因此二者庫的二進位制是不相容的。通俗的說就是把這些常用函式的目標檔案打包在一起,提供相應函式的介面...