大體步驟:動態鏈結器的自舉(與
.dynamic
段有關)裝載共享物件(涉及全域性符號表,符號優先順序等) 重定位與初始化
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
1>gcc -xlinker -rpath ./
表示鏈結器在當前路徑尋找共享物件
2>
當共享庫被裝載到程序的位址空間,則同時它們中的符號都會被併入到全域性符號表
3>
完成自舉以後,動態鏈結器可將可執行檔案和鏈結器本身的符號都合併到乙個符號表中,我們可以稱它為全域性符號表。
4>
全域性符號的介入:乙個共享物件裡面的全域性符號被另乙個共享物件的同名全域性符號覆蓋的現象又被稱為全域性符號的介入。
5>
在linux
動態鏈結器這樣處理:它定義了乙個規則,那就是當乙個符號需要被加入全域性符號表時,如果相同的符號名已經存在,則加入的符號被忽略。(所以共享物件應該避免符號重名
6>stait func()
這種函式的寫法是將函式編譯成單元私有函式,確定不被其他的模組呼叫。即模組內部呼叫指令,無需處理
.got.plt
,可以加快呼叫速度。意味著不以跨模組模式產生**?
7>linux
在通過execve()
系統呼叫被裝載到程序的虛擬空間,將控制權交給動態鏈結器。對於靜態鏈結程式的入口就是
elf檔案頭裡面的
e_entry
入口位址。對於動態鏈結來說,核心會分析動態鏈結器位址(在
.interp
段)。將動態鏈結器對映到程序位址空間,然後把控制權交給動態鏈結器。其實共享物件和可執行檔案沒有本質的區別,在
windows
裡面也有乙個叫做
rundll32.exe
工具可以直接
.dll
檔案
8>linux
的動態鏈結器是
glibc
的一部分,它的原始碼位於
glibc
的源**的
elf目錄下面
關於動態鏈結器:
1>
動態鏈結器本身應該是靜態鏈結的,它本身不依賴任何共享物件
2>
不一定必須是
pic,但是它是
pic的。帶來很多好處
共享庫組織
1>linux
的共享庫命名
libname.so.x.y.z x
主版本號,
y次版本號
z發布版本號。
不同主版本號完全不相容,改變了裡面的藉口。 此版本號增加新的介面,向下相容。 發布版本號介面不變,僅是內部改動。
2>
用so-name
so-name,
無需使用詳細的版本號,提供了更新上的方便。
3>
當共享庫
公升級:如果沒有進行主版本號公升級,則直接用新版本的共享庫替換掉舊版本,並修改
so-name
軟鏈結指向新版本; 但是如果進行了主版本號公升級系統就會存在多個
so-neme
乙個新乙個舊的,這樣也不會影響舊程式的執行
4>
總之,so-name
表示乙個庫的介面,介面不向後相容,
so-name
就發生變化。
5>
安裝共享庫後,
linux
中提供了
ldconfig
工具會搜尋
/lib /usr/lib
所有共享庫目錄,然後更新所有的軟鏈結。
靜態鏈結和動態鏈結
靜態載入dll dll工程b 專案屬性 配置屬性 常規 配置型別 動態庫 dll 在宣告檔案中,宣告匯出函式 declspec dllexport int xx 如果是c檔案,要在c 檔案中被呼叫,註明extern c 可以 ifdef cplusplus extern c endif 呼叫dll的...
靜態鏈結和動態鏈結
1 靜態鏈結庫只包含 lib檔案 動態鏈結庫包含 lib檔案和dll檔案,靜態鏈結庫中不能再包含其他的動態鏈結庫或者靜態庫,而在動態鏈結庫中還可以再包含其他的動態或靜態鏈結庫。此外他們都會用到定義了函式和相關資料結構的.h標頭檔案,其中 h標頭檔案是編譯時必須的,lib是鏈結時需要的,dll是執行時...
靜態鏈結和動態鏈結
動態鏈結庫 靜態庫 import庫區別 windows為應用程式提供了豐富的函式呼叫,這些函式呼叫都包含在動態鏈結庫中。其中有3個最重要的dll,kernel32.dll,它包含用於管理記憶體 程序和執行緒的各個函式 user32.dll,它包含用於執行使用者介面任務 如視窗的建立和訊息的傳送 的各...