回覆列表
  • 1 # 使用者2525411819162

    這個動態庫在執行時是怎樣載入進實驗室那邊的程式裡的?在linux上,你在ps中說的那種"將動態庫作為一個引數傳到程式裡"的使用方式,是透過dlopen函式將.so載入到當前程序中,並且透過ld.so將.so"連結"進當前程序。這個"連結"過程包括:查詢未定義符號在當前程序中的地址、分配資料/程式碼/bss段記憶體(資料初始化全域性變數、程式碼段重定位)、執行constructor函式等。之後,可以使用dlsym在已知符號名的情況下透過符號名查詢符號對應的地址。這個符號可以是一個全域性變數、全域性函式等。在你說的C++中,過載的函式也可以理解為全域性函式,會有一個屬性為weak的符號。該符號的符號名如果不做修改,預設按照System V的C++ API命名規範命名(以保證linux下不同編譯器編譯出來的.so和.o可以通用)。但如果使用extern "C"修飾之後,變成C的函式名,則無名稱修飾,便於使用。它怎樣例項化我實現的繼承類?例項化的方式和正常連結一樣。例如你在之類Derived中過載了基類Base中函式virtual void foo();那麼你需要在你的.so中匯出一個可以new Derived()的函式,並且返回結果為Base *,這樣別人可以在沒有Derived定義的情況下獲得執行時型別為Derived的物件。此時別人雖然只有Base *的型別,但是仍然可以和正常連結一樣透過虛表查virtual void foo()的地址,從而呼叫你定義的foo()。此外,如果你定義了繼承類的全域性變數,在載入.so的時候該全域性變數會自動初始化,你也可以將這個初始化的類透過指向Base *的指標傳出去。如果有大神能解釋一下windows下動態庫和靜態庫的原理,小弟感激不盡!和Linux差不多,不過在實現細節上有些出入。例如windows連結時要直接連結.dll需要透過連結生成這個.dll時生成的.lib,而Linux上直接連結.so即可。不過執行時連結無需這個.lib。靜態庫都是目標檔案的壓縮包。都是ELF格式。至於共享記憶體之類的,僅僅取決於section的屬性。

  • 中秋節和大豐收的關聯?
  • 關羽和張飛當初若不遇劉備,而是跟隨曹操,能混得更好嗎?