C語言中連接器介紹


       在C語言中。一個重要的思想就是分別編譯。即若干個源程序能夠在不同的時候單獨進行編譯。然后在恰當的時候整合到一起。可是連接器通常是與C編譯器分離的,連接器怎樣做到把若干個C源程序合並成一個總體呢?

       典型的連接器把由編譯器或匯編器生成的若干個目標模塊。整合成一個被稱為加載模塊或可運行文件的實體,該實體可以被操作系統直接運行。當中。某些目標模塊是直接作為輸入提供給連接器的;而另外一些目標模塊則是依據連接過程的須要。從包含有類似printf函數的庫文件里取得的。

       連接器通常把目標模塊看成是由一組外部對象組成的。

每一個外部對象代表着機器內存中的某個部分。並通過一個外部名稱來識別。

因此,程序中的每一個函數和每一個外部變量,假設沒有被聲明為static,就都是一個外部對象。

某些C編譯器會對靜態函數和靜態變量的名稱做一定改變,將它們也作為外部對象。

因為經過了“名稱修飾”。所以它們不會與其它源程序文件里的同名函數或同名變量發生命名沖突。

       大多數連接器都禁止同一個加載模塊中的兩個不同外部對象擁有同樣的名稱。然而。在多個目標模塊整合成一個加載模塊時,這些目標模塊可能就包括了同名的外部對象。

連接器的一個重要工作就是處理這類命名沖突。

       處理命名沖突的最簡單辦法就是干脆全然禁止。

對於外部對象是函數的情形,這樣的做法是正確的。

一個程序假設包含兩個同名的不同函數。編譯器根本就不應該接受。而對於外部對象是變量的情形,問題就變得困難了。不同的連接器對這樣的情形有着不同的處理方式。

       如今講講連接器是怎樣工作的?

       連接器的輸入是一組目標模塊和庫文件。連接器的輸出是一個加載模塊。

連接器讀入目標模塊和庫文件。同一時候生成加載模塊。

對每一個目標模塊中的每一個外部對象,連接器都要檢查加載模塊,看是否已有同名的外部對象。假設沒有,連接器就將該外部對象加入到加載模塊中;假設有,連接器就要開始處理命名沖突。

       除了外部對象之外,目標模塊還可能包含了對其它模塊中的外部對象的引用。比如:一個調用了函數printf的C程序所生成的目標模塊。就包含了一個對函數printf的引用。

能夠猜測得出。該引用指向的是一個位於某個庫文件里的外部對象。在連接器生成加載模塊的過程中。它必須同一時候記錄這些外部對象的引用。當連接器讀入一個目標模塊時,它必須解析出這個目標模塊中定義的全部外部對象的引用。並作出標記說明這些外部對象不再是沒有定義的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM