在應用程式(或另乙個d l l)能夠呼叫d l l中的函式之前,d l l檔案映像必須被對映到呼叫程序的位址空間中。若要進行這項操作,可以使用兩種方法中的一種,即載入時的隱含鏈結或執行期的顯式鏈結。 這裡主要介紹隱式鏈結。
若要建立d l l模組,必須執行下列操作步驟:
1) 首先必須建立乙個標頭檔案,它包含你想要從d l l輸出的函式原型、結構和符號。d l l的所有源**模組均包含該標頭檔案,以幫助建立d l l。後面將會看到,當建立需要使用d l l中包含的函式和變數的可執行模組(或多個模組)時,也需要這個標頭檔案。
2) 要建立乙個c / c + +源**模組(或多個模組),用於實現你想要在d l l模組中實現的函式和變數。由於這些源**模組在建立可執行模組時是不必要的,因此建立d l l的公司能夠保護公司的秘密。
3) 建立d l l模組,將使編譯器對每個源**模組進行處理,產生乙個. o b j模組(每個源**模組有乙個. o b j模組)。
4) 當所有的. o b j模組建立完成後,鏈結程式將所有. o b j模組的內容組合在一起,產生乙個d l l映象檔案。該映像檔案(即模組)包含了用於d l l的所有二進位制**和全域性/靜態資料變數。為了執行這個可執行模組,該檔案是必不可少的。
5) 如果鏈結程式發現d l l的源**模組至少輸出了乙個函式或變數,那麼鏈結程式也生成乙個. l i b檔案。這個. l i b檔案很小,因為它不包含任何函式或變數。它只是列出所有已輸出函式和變數的符號名。為了建立可執行模組,該檔案是必不可少的。
一旦建立了d l l模組,就可以建立可執行模組。其建立步驟是:
6) 在引用函式、變數、資料、結構或符號的所有源**模組中,必須包含d l l開發人員建立的標頭檔案。
7) 要建立乙個c / c + +源**模組(或多個模組),用於實現你想要在可執行模組中實現的函式和變數。當然該**可以引用d l l標頭檔案中定義的函式和變數。
8) 建立可執行模組,將使編譯器對每個源**模組進行處理,生成乙個. o b j模組(每個源**模組有乙個. o b j模組)。
9) 當所有. o b j模組建立完成後,鏈結程式便將所有的. o b j模組的內容組合起來,生成乙個可執行的映像檔案。該映像檔案(或模組)包含了可執行檔案的所有二進位制**和全域性/靜態變數。該可執行模組還包含乙個輸入節,列出可執行檔案需要的所有d l l模組名。此外,對於列出的每個d l l名字,該節指明了可執行模組的二進位制**引用了哪些函式和變數符號。下面你會看到作業系統的引導程式將對該輸入節進行分析。一旦d l l和可執行模組建立完成,乙個程序就可以執行。當試圖執行可執行模組時,作業系統的引導程式將執行下面的操作步驟:
10) 引導程式為新程序建立乙個虛擬位址空間。可執行模組被對映到新程序的位址空間。引導程式對可執行模組的輸入節進行分析。對於該節中列出的每個d l l名字,引導程式要找出使用者系統上的d l l模組,再將該d l l對映到程序的位址空間。注意,由於d l l模組可以從另乙個d l l模組輸入函式和變數,因此d l l模組可以擁有它自己的輸入節。若要對程序進行全面的初始化,引導程式要分析每個模組的輸入節,並將所有需要的d l l模組對映到程序的位址空間。如你所見,對程序進行初始化是很費時間的。
1。輸出的真正含義是什麼
介紹乙個真正有意思的東西是_ _ d e c l s p e c ( d l l e x p o r t )修改符。當m i c r o s o f t的c / c + +編譯器看到變數、函式原型或c + +類之前的這個修改符的時候,它就將某些附加資訊嵌入產生的. o b j檔案中。當鏈結d l l的所有. o b j檔案時,鏈結程式將對這些資訊進行分析。當d l l被鏈結時,鏈結程式要查詢關於輸出變數、函式或c + +類的資訊,並自動生成乙個. l i b檔案。該. l i b檔案包含乙個d l l輸出的符號列表。當然,如果要鏈結引用該d l l的輸出符號的任何可執行模組,該. l i b檔案是必不可少的。除了建立. l i b檔案外,鏈結程式還要將乙個輸出符號表嵌入產生的d l l檔案。這個輸出節包含乙個輸出變數、函式和類符號的列表(按字母順序排列)。該鏈結程式還將能夠指明在何處找到每個符號的相對虛擬位址( rva)放入d l l模組。
2。建立可執行模組
當建立可執行源**檔案時,必須加上d l l的標頭檔案。如果沒有標頭檔案,輸入的符號將不會被定義,而且編譯器將會發出許多警告和錯誤訊息。
可執行源**檔案被編譯時,使用_ _ d e c l s p e c ( d l l i m p o r t )進行定義。當編譯器看到修改變數、函式或c + +類的_ _ d e c l s p e c ( d l l i m p o r t )時,它知道這個符號是從某個d l l模組輸入的。它不知道是從哪個d l l模組輸入的,並且它也不關心這個問題。編譯器只想確保你用正確的方法訪問這些輸入的符號。現在你在源**中可以引用輸入的符號,一切都將能夠正常工作。
接著,鏈結程式必須將所有. o b j模組組合起來,建立產生的可執行模組。該鏈結程式必須確定哪些d l l包含**引用的所有輸入符號的d l l。因此你必須將d l l的. l i b檔案傳遞給鏈結程式。如前所述, . l i b檔案只包含d l l模組輸出的符號列表。鏈結程式只想知道是否存在引用的符號和哪個d l l模組包含該符號。如果連線程式轉換了所有外部符號的引用,那麼可執行模組就因此而產生了。
3。輸入的真正含義是什麼
上一節介紹了修改符- - d e c l s p e c ( d l l i m p o r t )。當輸入乙個符號時,不必使用關鍵字- -d e c l s p e c ( d l l i m p o r t ),只要使用標準的c關鍵字e x t e r n即可。但是,如果編譯器預先知道你引用的符號將從乙個d l l的. l i b檔案輸入,那麼編譯器就能夠生成執行效率稍高的**。因此建議你盡量將- - d e c l s p e c ( d l l i m p o r t )關鍵字用於輸入函式和資料符號。當你呼叫標準wi n d o w s函式中的任何乙個時,m i c r o s o f t將為你進行這項設定。
當鏈結程式進行輸入符號的轉換時,它就將乙個稱為輸入節的特殊的節嵌入產生的可執行模組。輸入節列出了該模組需要的d l l模組以及由每個d l l模組引用的符號。
4。執行可執行模組
當乙個可執行檔案被啟動時,作業系統引導程式將為該程序建立虛擬位址空間。然後,引導程式將可執行模組對映到程序的位址空間中。引導程式檢視可執行模組的輸入節,並設法找出任何需要的d l l,並將它們對映到程序的位址空間中。
2021 01 06 隱式鏈結
dll編譯完成後生成 dll與 lib,但其生成的 lib檔案與靜態鏈結庫的不同,動態鏈結庫中的 lib裡不包含 只包含一些輔助性的資訊。如果有了 dll與 lib檔案即可使用隱式鏈結。declspec dllimport stdcall int plus int x,int y declspec ...
Dll動態鏈結庫建立與隱式鏈結方式使用
windows作業系統誕生以來,dll就作為win作業系統的基礎,通常情況下dll不能直接執行,也無法接收訊息,只能供其他可執行程式或者dll來呼叫,完成某項功能,他的函式只有被呼叫才會發揮作用,windows中有三個重要的dll,他們分別是kernal32.dll,user32.dll,gdi32...
隱式鏈結隱式鏈結 第1部分 了解隱式跟蹤
該帖子的編輯日期為 2019年7月22日 以便在重疊網格專案的示例中更好地描述專案放置。當觀察人們逐漸熟悉css grid時,我注意到一些問題比其他人更容易吸引人們,或者在構建布局時面臨更多挑戰。本簡短的系列文章將深入 這些常見問題,旨在更好地理解grid,以便您可以預期布局問題,並在出現問題時更輕...