庫是我們經常要是用的東西。庫分為兩種 靜態庫和動態庫。 兩種的共同點是實現了**的重用。但是靜態庫是是編譯之後就別打包到exe可執行檔案中去了,但是動態庫不是的,他可以顯示的載入,在你需要的時候。當然也可以隱式載入。這樣的話,顯然他不是被打包到exe中去的。
我們先來看兩種庫的檔案構成。 靜態庫是乙個lib檔案,但是給到使用者的時候,往往會有乙個標頭檔案。來宣告庫裡面的函式。動態庫的構成呢。也是乙個lib檔案,乙個dll檔案。通常也會有乙個標頭檔案給到使用者。但是這裡兩個lib檔案的是根本不同的。靜態庫的lib檔案就是庫的實際**和符號表等,而動態庫的lib檔案呢。其實他是乙個導入庫,導入庫只包含了位址符號表等,確保程式找到對應函式的一些基本位址資訊。
兩種庫的生成方式。對於靜態庫來說,他是在鏈結時與彙編生成的obj檔案鏈結在一起,打包到exe檔案中。所以lib檔案格式與obj檔案格式相類似。由於lib檔案時打包到exe檔案中去的,所以可執行檔案執行時是可以脫離靜態庫檔案的。這樣的話,移植很方便。同樣也造成了浪費。
對於動態庫來說,在鏈結的時候,並沒有將dll打包到exe檔案中,只是告訴了鏈結器導入庫,這裡記載函式的位址的符號表,用於定位。執行時,去載入dll。所以
exe檔案執行時是不能離開dll的。這樣的可執行檔案的移植不如靜態庫方便。節省了資源。
兩種庫檔案的的呼叫方式都用兩種顯示和隱式。對於靜態庫來說 ,隱式呼叫就是在vs 中在專案屬性中link的input 中新增依賴項。顯式呼叫就是使用#pragma comment(lib,"..\xx.lib")。 對於動態庫的話也有顯式和隱式呼叫區分。隱式呼叫就是在專案屬性中的link 的input新增依賴項。對於顯式呼叫的時候,就是用loadlibrary獲得模組的控制代碼,然後用getprocaddress 獲取函式位址,這樣去呼叫函式。但是我們在顯示呼叫的時候庫檔案時,庫檔案的匯出函式就必須要extern 「c」 修飾。這個是由於getprocaddress 這些函式的api 的介面是是標準c的介面的。顯式的去呼叫的時候我們只能extern "c"修飾。所以這個是不支援過載的。對於類的匯出也是很複雜的,所以不建議使用顯式呼叫dll。如果我們dll函式是有過載的,我們在使用dependency 工具去檢視的時候會發現 用extern 「c」修飾的函式和沒有用extern 「c」修飾的函式 函式名字是不一樣的。這些函式是這個dll的模組的真正的函式入口。當我們使用不同的呼叫約定的方式的時候,函式名也會不一樣。我們會發現在顯式呼叫的時候,我們使用getprocaddress 填上真正函式名時時有函式入口位址返回的。這是還要dll裡面匯出函式的呼叫約定,是__cdecl 還是__stdcall 的,c,c++的呼叫約定方式__cdcel。不過dll呼叫約定方式__stdcall的話,register 會報錯。
靜態庫的建立和使用
在我們的應用中,有一些公共 是需要反覆使用,就把這些 編譯為 庫 檔案 在鏈結步驟中,聯結器將從庫檔案取得所需的 複製到生成的可執行檔案中。這種庫稱為靜態庫,其特點是可執行檔案中包含了庫 的乙份完整拷貝 缺點就是被多次使用就會有多份冗餘拷貝。一 建立靜態庫 編譯器 vs2010 建立乙個 win32...
建立和使用靜態庫
我們通常把一些公用函式製作成函式庫,供其它程式使用。函式庫分為靜態庫和動態庫兩種。靜態庫在程式編譯時會被連線到目標 中,程式執行時將不再需要該靜態庫。動態庫在程式編譯時並不會被連線到目標 中,而是在程式執行是才被載入,因此在程式執行時還需要動態庫存在。本文主要通過舉例來說明在linux中如何建立靜態...
建立和使用靜態庫
測試可用 我們將建立的下乙個庫型別是靜態庫 lib 使用靜態庫是重用 的一種絕佳方式。您不必在自己建立的每個程式中重新實現同一例程,而只需對這些例程編寫一次,然後從需要該功能的應用程式引用它們即可。本演練演示如何完成以下任務 本主題假定您具備 c 語言的基礎知識。如果您是剛開始學習 c 建議參閱 m...