大家都知道應用程式有兩種連結方式,一種是靜态連結,一種是動态連結,這兩種連結方式各有好處。
程式的靜态連接配接還是動态連接配接是根據編譯器的連接配接參數指定的。
所謂靜态連結就是在編譯連結時直接将需要的執行代碼拷貝到調用處,優點就是在程式釋出的時候就不需要的依賴庫,也就是不再需要帶着庫一塊釋出,程式可以獨立執行,但是體積可能會相對大一些。(所謂庫就是一些功能代碼經過編譯連接配接後的可執行形式。)
所謂動态連結就是在編譯的時候不直接拷貝可執行代碼,而是通過記錄一系列符号和參數,在程式運作或加載時将這些資訊傳遞給作業系統,作業系統負責将需要的動态庫加載到記憶體中,然後程式在運作到指定的代碼時,去共享執行記憶體中已經加載的動态庫可執行代碼,最終達到運作時連接配接的目的。優點是多個程式可以共享同一段代碼,而不需要在磁盤上存儲多個拷貝,缺點是由于是運作時加載,可能會影響程式的前期執行性能。
上面的都是一些概念性的,也是比較簡單的,可能大家都知道,但是具體的實作方式是什麼樣的那?比如兩個最主流的作業系統windows和linux是怎麼實作的。
windows:
在windows上大家都是DLL是動态連結庫,裡面是一系列可執行的代碼,開發過windows程式的人可能還知道有另外一種形式的庫,就是LIB,大家可能普遍認為LIB就是靜态庫,至少我之前是這麼認為的,但是在實際的開發過程中,糾正了我這個錯誤的想法。LIB形式的檔案可能會有兩種形式,這裡并不排除第三種形式。1:包括符号表和二進制可執行代碼,也就是傳統意義上了解的靜态庫,可以被靜态連接配接。2:隻有符号表,也就是隻有動态庫的符号導出資訊,通過這些資訊可以在程式運作時定位到動态庫中,最終實作動态連接配接。
linux:
在linux上大家也都知道SO是動态庫,類似于windows下的DLL,實作方式也是大同小異,同時開發過linux下程式的人也都知道另外一種形式的庫就是A庫,同樣道理普遍認為是和SO對立的,也就是靜态庫,不然沒道理存在啊,呵呵。但是事實區卻不是如此,A檔案的作用和windows下的LIB檔案作用幾乎一樣,也可能會有兩種形式,和windows下的lib檔案一樣,在此就不在贅述。
對于兩個平台下我認為是靜态庫的竟然還有第二種情況(就是LIB和A不隻是靜态庫)是我萬萬沒有想到的,對此我感到非常詫異,可能大家都意識到了(隻有我沒意識到),再此對自己批評一番!
經過這樣一說可能大家都會明白了(也許你已經明白),在以後的開發中可能也都會用心一點,其實很多東西都不是我們表面上看來的那麼簡單,上面的了解和解釋不一定全對,但是确實我在實際開發中所發現的,大家僅僅作為參考就行。在此我也告誡自己,凡事不能想當然,不能以自己所知道和了解的那一點做為正确答案,要善于學習,善于向比自己強的人學習,要勇敢的面對自己的錯誤!