動態鏈結和靜態鏈結的區別
一、分別編譯與鏈結(linking)
大多數高階語言都支援分別編譯,程式設計師可以顯式地把程式劃分為獨立的模組或檔案,然後每個獨立部分分別編譯。在編譯之後,由鏈結器把這些獨立的片段(稱為編譯單元)「粘接到一起」。(想想這樣做有什麼好處?)
在c/c++中,這些獨立的編譯單元包括obj檔案(一般的源程式編譯而成)、lib檔案(靜態鏈結的函式庫)、dll檔案(動態鏈結的函式庫)等。
二、靜態鏈結庫與動態鏈結庫
先來闡述一下dll(dynamic linkable library)的概念,你可以簡單的把dll看成一種倉庫,它提供給你一些可以直接拿來用的變數、函式或類。
靜態鏈結庫與動態鏈結庫都是共享**的方式,如果採用靜態鏈結庫,則無論你願不願意,lib中的指令都被直接包含在最終生成的exe檔案中了。但是若使用dll,該dll不必被包含在最終的exe檔案中,exe檔案執行時可以「動態」地引用和解除安裝這個與exe獨立的dll檔案。
三、認識動態鏈結庫
動態鏈結是相對於靜態鏈結而言的。所謂靜態鏈結是指把要呼叫的函式或者過程鏈結到可執行檔案中,成為可執行檔案的一部分。換句話說,函式和過程的**就在程式的exe檔案中,該檔案包含了執行時所需的全部**。當多個程式都呼叫相同函式時,記憶體中就會存在這個函式的多個拷貝,這樣就浪費了寶貴的記憶體資源。而動態鏈結所呼叫的函式**並沒有被拷貝到應用程式的可執行檔案中去,而是僅僅在其中加入了所呼叫函式的描述資訊(往往是一些重定位資訊)。僅當應用程式被裝入記憶體開始執行時,在windows的管理下,才在應用程式與相應的dll之間建立鏈結關係。當要執行所呼叫dll中的函式時,根據鏈結產生的重定位資訊,windows才轉去執行dll中相應的函式**。一般情況下,如果乙個應用程式使用了動態鏈結庫,win32系統保證記憶體中只有dll的乙份複製品
(1) 裝載時動態鏈結(load-time dynamic linking):這種用法的前提是在編譯之前已經明確知道要呼叫dll中的哪幾個函式,編譯時在目標檔案中只保留必要的鏈結資訊,而不含dll函式的**;當程式執行時,呼叫函式的時候利用鏈結資訊載入dll函式**並在記憶體中將其鏈結入呼叫程式的執行空間中(全部函式載入進記憶體),其主要目的是便於**共享。(動態引導程式,處在載入階段,主要為了共享**,共享**記憶體)
(2) 執行時動態鏈結(run-time dynamic linking):這種方式是指在編譯之前並不知道將會呼叫哪些dll函式,完全是在執行過程中根據需要決定應呼叫哪個函式,將其載入到記憶體中(只載入呼叫的函式進記憶體),並標識記憶體位址,其他程式也可以使用該程式,並用loadlibrary和getprocaddress動態獲得dll函式的入口位址。(dll在記憶體中只存在乙份,處在執行階段)
上述的區別主要在於階段不同,編譯器是否知道程序要呼叫的dll函式。動態載入在編譯時知道所呼叫的函式,而在執行態時則必須不知道。
動態鏈結和靜態鏈結的區別
一 分別編譯與鏈結 linking 大多數高階語言都支援分別編譯,程式設計師可以顯式地把程式劃分為獨立的模組或檔案,然後每個獨立部分分別編譯。在編譯之後,由鏈結器把這些獨立的片段 稱為編譯單元 粘接到一起 想想這樣做有什麼好處?在c c 中,這些獨立的編譯單元包括obj檔案 一般的源程式編譯而成 l...
動態鏈結和靜態鏈結
在類的習慣性用法中,我們提到 對於類中 量較多的成員函式,僅僅在標頭檔案的類中宣告成員和函式用法,而將方法封裝起來。對於 量較大的成員函式來說,直接把 放在類中定義存在兩個問題 一是使用起來很不方便,二是破壞了資訊隱藏機制。那麼為什麼說將 放在類中定義會破壞資訊隱藏機制呢?實際上,對於變數和函式,一...
動態鏈結和靜態鏈結
庫從本質上來說是一種可執行的二進位制檔案,可以被載入到記憶體中執行,而根據鏈結時期的不同,庫又可以分為靜態庫和動態庫。靜態鏈結就是在編譯時將多個目標檔案組合在一起形成乙個可執行檔案的過程。1.空間與位址的分配過程中,首先會掃瞄所有的輸入檔案,獲得他們的各個段的長度,屬性和位置,然後將輸入檔案中所有的...