Unix/Linux 環境中的動態連結類型
創建 Windows 靜態庫時,我們只需創建一個 .lib 文件,該文件應包含在連結器路徑中。
在創建 Windows 共享庫時,與 .dll 一起,我們還生成了一個 .lib 文件。此庫文件包含庫公開的 API 的簽名。
有兩種方法可以使用這個庫
- 我們可以直接在我們的項目中引用庫 API 並在連結器屬性中添加 .lib 文件的路徑。有人稱其為靜態連結動態庫
- 或者我們可以在執行時顯式載入動態庫。在這種情況下,我們不需要指定連結器的 lib 文件路徑。稱它為動態連結的動態庫。
我的問題是我們在 Linux 上是否也有類似的共享庫?還是只是靜態庫 (.a) 和共享庫 (.so)?
我知道如何使用 gcc -l 選項在 linux 上包含一個靜態庫。我們可以使用相同的選項來包含動態庫(.so)嗎?
我不能說我理解什麼是“靜態連結的動態庫”,我也對庫中包含的簽名一無所知(雖然聽起來很有趣:這是否意味著連結器能夠檢查參數中的類型不匹配並在連結處返回類型時間?ELF肯定沒有這樣的功能。)所以這個答案不會是從比較的角度來看的。另外,由於您的問題非常廣泛,因此詳細的答案將是膚淺的。
是的,您可以創建靜態庫 (
.a
) 或共享庫 (.so
)。當連結器查找-l
使用-static
.從原始碼建構庫時,只需將其建構為靜態庫 (
.a
) 或共享庫 (.so
),而不是兩者。儘管如此,還是設置了相當多的包的建構腳本來建構兩個版本(這需要編譯兩次,一次使用與位置無關的程式碼,一次沒有),以便讓庫的使用者選擇要連結哪一個。靜態庫的必要部分完全合併到建構的二進製文件中。無需
.a
在執行時提供該文件。相反,連結到二進製文件的共享庫必須在執行時可用,儘管執行時動態連結器通常會在修改後的名稱下搜尋它,它的“soname”(通常libsomething.so
在連結時和libsomething.so.<integer>
執行時),該功能允許在系統中同時安裝具有略微不同 API 的庫的多個不同版本。在您的問題中,您還提到在執行時顯式載入動態庫。這通常用於模組化應用程序或帶有外掛的應用程序。在這種情況下,有問題的庫(通常稱為“模組”或“外掛”)根本沒有與應用程序連結,建構時連結器對此一無所知。相反,應用程序開發人員必須編寫程式碼來呼叫執行時動態連結器,並要求它按文件名或完整路徑名打開庫。有時,要打開的模組的名稱列在應用程序的配置文件中,或者有一些其他的應用程序邏輯決定哪些模組是需要或不需要的。