linux下C C 開發小記2

2021-10-10 03:32:57 字數 1539 閱讀 4059

dlopen函式介紹

void * dlopen(const char* pathname, int mode);

在這裡針對該函式的返回值,引數記錄下自己的理解。

在載入庫失敗時會返回空指標,此時可以使用dlerror輸出錯誤原因,至於為什麼失敗會與傳入的引數有關。

要動態載入的庫的名字,可以是相對路徑也可以是絕對路徑。個人建議為避免載入庫錯誤最好是傳入帶有絕對路徑的庫名。

dlopen載入庫的情況:1.如果filename中含有"/",且不是以「/」開頭則是相對路徑,是以woking directoy進行相對查詢;如果是以「/」開頭,則是絕對路徑。2.直接指定庫的名字,不含「/」,此時查詢庫會以rpath->ld_library->ld.so.cache->/lib,/usr/lib順序進行查詢。

rtld_lazy:針對庫中的函式,特指程式中實際用到的函式,在載入時不立馬解析和重定位,只有在執行到函式所在位置時才解析函式符號,這樣做的好處是提公升載入庫的速度,但壞處是:當實際用到的函式在實際執行過程中找不到位址資訊時會造成整個程式的崩潰,但dlopen是返回的成功的,即沒有第一時間返回錯誤。

rtld_now:不同於rtld_lazy,在載入庫時便會完成函式符號的解析和重定位工作,若有函式找不到位址(例如只宣告了該函式,並在程式中使用該函式)則dlopen會立馬返回null。注意rtld_lazy和rtld_now必須手動設定乙個。

rtld_global:開啟的庫會將自己的全域性符號暴露到全域性符號表中,這樣會被後續載入的模組用來重定位。

rtld_local:開啟的庫不會將自己的全域性符號暴露到全域性符號表中,這樣也就不會被後續載入的模組用來重定位,預設使用改引數

rtld_deepbind:這個引數將在下文中進行解釋。

void * dlsym(void * handle, const char* symbol);

1.當handle為null時,鏈結器會從全域性符號表中去解析和重定位symbol;

2.當handle為有效模組指標時,鏈結器只會從指定的庫中解析符號,若找不到則返回空指標。

在使用dlopen時同樣會面臨內部全域性符號和外部全域性符號重名的問題,這種問題帶來的主要影響是:在使用dlsym拿到我們要使用的函式符號時(這個符號確實是指定載入庫中的符號),但是該函式依賴模組內部的其他符號,但該符號與外部函式同名,這就會導致執行錯誤甚至崩潰。

為解決上述問題當然可以採用《linux下c/c++開發小記1》中說的在編譯鏈結生成庫的階段搞定,而dlopen也為我們提供了解決思路那就是rtld_deepbind引數,使用該引數可以使被顯示動態載入的模組優先使用其內部符號,而不是已存在與全域性符號表中的符號

Uranus開發小記 2

為了讓uranus能注入到x86和x64程序中,uranus必須知道x86和x64平台中loadlibrary函式的位址。我們將uranus設定為32位,則x86平台的loadlibrary位址可以簡單的獲得。下一步,檢測作業系統平台是x86還是x64 方法下面提到 若為x64,則啟動乙個新的x64...

學習LINUX下的C C 開發

目的 為了學習linux下的c c 開發。虛擬機器中安裝ubuntu16.04lts 14.04.5也可以,只是最後clion要求的gdb版本會不達標,更新gdb會比較麻煩 2.更新apt的國內源,這樣在安裝軟體和更新,速度會更快 sudo vi etc apt source.list sudo a...

Unix Linux下C C 開發技術概覽2

1.3 圖形使用者介面 windows 和unix 圖形模型差異極大,這點是unix和windows程式開發最大的差別。unix 使用x window 系統gui,而windows 使用gdi。雖然在概念上類似,但是x api 和gdi api 之間沒有簡單的對應。在windows下面可以通過mfc...