靜態鏈接和動態鏈接

大家都知道應用程序有兩種鏈接方式,一種是靜態鏈接,一種是動態鏈接,這兩種鏈接方式各有好處。

程序的靜態連接還是動態連接是根據編譯器的連接參數指定的。

所謂靜態鏈接就是在編譯鏈接時直接將需要的執行代碼拷貝到調用處,優點就是在程序發佈的時候就不需要的依賴庫,也就是不再需要帶着庫一塊發佈,程序可以獨立執行,但是體積可能會相對大一些。(所謂庫就是一些功能代碼經過編譯連接後的可執行形式。)

所謂動態鏈接就是在編譯的時候不直接拷貝可執行代碼,而是通過記錄一系列符號和參數,在程序運行或加載時將這些信息傳遞給操作系統,操作系統負責將需要的動態庫加載到內存中,然後程序在運行到指定的代碼時,去共享執行內存中已經加載的動態庫可執行代碼,最終達到運行時連接的目的。優點是多個程序可以共享同一段代碼,而不需要在磁盤上存儲多個拷貝,缺點是由於是運行時加載,可能會影響程序的前期執行性能

理解靜態鏈接和動態鏈接 前些日子在論壇上看到這樣兩個問題:

1、什麼叫靜態鏈接和動態鏈接?(static linking,dynamic linking)

 2、如何理解先期和遲後聯編?(early binding,later binding)

3、連接時所需的庫lib和dll。

 

實際上,這兩個問題性質是一樣的,不管是靜態鏈接/動態鏈接也好,還是先期聯編/遲後聯編也好,都是描述了何時確定應用程序所調用函數的入口地址,如果編譯器在編譯時或鏈接時確定了所有函數的入口地址,那麼這種確定地址的方法稱爲靜態鏈接或者先期聯編。如果是在運行時確定所有函數的入口地址,那麼這種確定地址的方法稱爲動態鏈接或者遲後聯編。C++通過使用虛擬函數支持動態鏈接/遲後聯編(也叫做動態聯編),它們發生在運行時刻,這樣一來,使用多重繼承的程序便會有更大的靈活性。

下面我們用一段代碼來加以說明:

 class A {

          public:   A();  

          int memberFunc();  

          virtual int virtualFunc(); 

          static int staticFunc()' } main() {   A* pa;   //  ... - initializing pa   pa->memberFunc();   pa->vitrualFunt();   pa->staticFunc(); }

當編譯這段代碼時,編譯器在編譯期間可以知道確切的函數信息,比如函數署名叫:“memberFunc”、“staticFunc”等----此即爲靜態鏈接/先期聯編。但是在調用virtualFunc函數時,只能在運行時得知該函數的信息,此時函數纔會被真正調用,因爲代碼可能是下面這樣的: class B : public A { public   //...   virtual int virtualFunc(); } 並且如果 'pa' 被賦值 pa = new B(); 那麼類B的函數將會被調用並執行----此即爲動態鏈接/遲後聯編。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章