vc的靜態庫依賴

2021-07-22 06:34:57 字數 1534 閱讀 8850

@(技術部落格)

vc編譯的靜態庫.lib檔案是一系列.obj檔案的集合,這點和linux系統上的靜態庫一致,但是vc的靜態庫有乙個獨有的功能,強制這個靜態庫的使用者必須鏈結某個庫。這點在靜態庫已經有很複雜的依賴關係或者需要強制鏈結某個版本的庫時及其有用。

否則,如果靜態庫中用到了其他的庫,需要這個靜態庫的使用者在最終的鏈結階段清楚所有使用到的庫,然後一一鏈結。

如果靜態庫依賴的庫很多的話,而且依賴的關係很複雜,那麼對於最終的使用者來說絕對是一場噩夢。

在linux下,我們可以將所有依賴的庫全部解壓 再打包到乙個庫中實現,但是這個方法還有一些問題,而且操作也比較麻煩。具體內容我在另一篇部落格中已經詳細描述了,這裡不再贅述。

但是vc編譯器卻可以毫無***的完美實現這個功能,並不增大庫的體積,而且也可以鏈結動態庫,這到底怎麼實現的呢?

有兩種方法可以做到這一點:

vc的鏈結器有乙個引數/defaultlib:library ,可以將library 新增到 link 在解析引用時搜尋的庫列表(這是官方翻譯),其實意思就是指會強制這個庫的使用者鏈結某個庫。

這個引數只能在使用命令列的時候使用,vs介面中沒有任何乙個地方可以設定這個選項。

vs的靜態庫專案設定頁裡有乙個庫管理器的東西,裡面可以設定要鏈結的庫,但是其實就是將所有的庫解開後再全部打包,和linux上的方案一樣,會造成庫的體積劇烈膨脹,我們通常並不會用這種方法。

在**中插入這個選項可以自動鏈結乙個庫,免去在vs的專案配置中指定鏈結的庫。但是如果此專案是乙個靜態庫,他就會和使用defaultlib的效果一樣了。考慮到大多數人應該不是使用命令列來編譯,所以這應該是大多數人使用的方法。

但是實現這個功能的原理是什麼呢?為什麼linux實現不了呢?

這就要提到vc編譯的一些細節了。眾所周知,vc編譯後的obj目標檔案是一種coff檔案,而coff檔案是分段的。其中vc鏈結器規定了乙個特殊的段.drectve,這個段內容是編譯器傳遞給鏈結器的指令。而vc的靜態庫依賴就是靠這個實現的。/defaultlib選項和pragma comment都會將庫資訊寫在這個段裡。然後庫的使用者在鏈結的時候自然就會讀取到這個資訊然後自動鏈結。

也就是說這個資訊是寫在obj目標檔案裡的,並不是寫在.lib靜態庫檔案裡的。

那麼怎麼檢視指定鏈結了哪些庫呢?有以下的方法:

- 使用vc提供的檢視工具dumpbin /directives檢視.lib或者objdrectve資訊,但是release版會隱藏這些資訊,不一定能看到。

- 直接以文字模式開啟.lib或者obj檔案,搜尋.lib字元,就可以找到相應的資訊。這個方法在release版下也能使用.

VC靜態庫的除錯

對於動態庫或者可執行程式而言,如果想要除錯只要將對應的pdb檔案和動態庫或者可執行檔案放在一起即可自動載入符號。眾所周知靜態庫在最終鏈結的時候是把 直接鏈結到最終的生成檔案裡的。這就決定了不可能把靜態庫的pdb檔案和生成檔案放在一起來除錯。所以我們想要除錯靜態庫,肯定需要一些特殊的操作。那麼,對於靜...

VC 載入動態庫和靜態庫

靜態庫包括.lib和.h檔案,在工程中使用靜態庫分為3步 1在工程中加入靜態庫,有兩種方法 方法一 專案設定中引用.lib,project setting link object library modules中新增.lib 需要在tools options設定正確的引用路徑 方法二 在專案中直接加...

關於VC 中靜態庫的呼叫

關於vc 中靜態庫的呼叫 這個靜態庫是通過 通過生成嚮導選擇win32 static library建立的。在這個庫的生成嚮導中有兩個選項 pre compiled header 是在生成的工程中新增 stdafx.h 預編譯標頭檔案 mfc support 是在生成的工程中新增對mfc的支援,也就...