一、源代碼-面向CLR的編譯器-托管模塊-(元數據&IL代碼)


本文脈絡圖如下:

1、CLR(Common Language Runtime)公共語言運行時簡介

(1)、公共語言運行時是一種可由多種編程語言一起使用的"運行時".

(2)、CLR的核心功能可由面向CLR的所有語言使用,例如:"運行時"使用異常來報告錯誤,因此面向CLR的所有語言都使用異常來報告錯誤.另外,CLR允許創建線程,所以所有面向CLR的編程語言都允許創建線程.

(3)、運行時,CLR並不關心程序使用的是哪種語言,只要該語言是面向CLR的就行.

 

2、面向CLR的語言編譯器

 

3、面向CLR的語言編譯器編譯源代碼的過程,以C#為例

我們可以使用任何面向CLR的語言創建源文件,然后用對應的編譯器去檢查語法和源代碼,無論選擇哪個編譯器,通過編譯器編譯后生成的都是托管模塊((IL)中間語言和元數據的組合).

本地代碼編譯器(native code compilers)生成的是面向特定CPU架構(比如X86、X64、ARM)的代碼。相反,面向CLR的每個編譯器生成的都是IL(中間語言)代碼(IL代碼有時被稱為托管代碼,因為CLR管理它們的執行),除了生成IL(中間語言),面向CLR的每個托管模塊中生成完整的元數據.

(1)、托管模塊

托管模塊簡介

        標准的32位Microsoft Windows可移植執行體(PE32)文件

        標准的64位Microsoft Windows可移植執行體(PE32+)文件

它們都需要CLR才能執行.

注:托管模塊總是利用Windows的數據執行保護(Data Execution Prevention,DEP)和地址空間布局隨機化(Adress Space Layout Ramdomization),這兩個功能旨在增強整個系統的安全性.

托管模塊構成

PE32或PE32+頭:標准Windows PE文件頭,類似於"公共文件對象格式"(Common Object Format,COFF)頭。

注:如果文件頭使用PE32格式,文件能在Windows的32位版本和64位版本上運行,如果文件頭是PE32+格式,那么該文件只能在Windows64位版本上運行.

文件頭還標識了文件類型,包括GUI、CUI或者DLL,並包含一個時間標記來指出文件的生成時間.對於只包含IL代碼的模塊,PE32+頭的大多數信息會被忽視.如果是包含本機CPU代碼的模塊,這個頭包含與CPU代碼有關的信息.

CLR頭:包含使這個模塊成為托管模塊的信息(可由CLR和一些實用程序進行解釋),頭中包含要求的CLR版本,一些標志(flag),托管模塊入口方法(Main方法)的MethodDef元數據token以及模塊的元數據、資源、強名稱、一些標志項及其他一些不太重要的數據項的位置/大小

元數據:每個托管模塊都包含元數據表.主要有兩種表:一種表描述源代碼中定義的類型和成員,另一種描述源代碼中引用的類型和成員.

IL(中間語言)代碼:編譯器編譯源代碼時生成的代碼.在運行時,CLR將IL編譯成本機CPU指令.

 

(2)、元數據詳解

元數據簡介:

元數據大致構成:包括com的"類型庫"和"接口定義語言"(Interface Definition Language,IDL)文件,但CLR數據遠比它們全面.

注:元數據總是嵌入和代碼相同的EXE/DLL文件中,這使兩者密不可分,由於編譯器和源代碼同時生成元數據和代碼,把它們綁定到一起,並嵌入到最終生成的托管模塊,所以元數據和IL代碼永遠不會失去同步.

元數據的用途:

 

1、元數據避免了對原生C/C++頭和庫文件的需求,因為在實現類型/成員的IL代碼中,已經包含了有關引用類型/成員的全部信息,所以編譯器直接從托管模塊中讀取元數據即可.

2、visual stdio的智能提示通過解析元數據的方式,來告訴我們一個類型有哪些屬性、方法、字段、事件,來提高我們的開發效率.

3、CLR的代碼驗證過程中確保代碼只執行類型安全的操作.

4、元數據允許將對象的字段序列化到內存中,在發送到另外一台機器,進行反序列化,重塑對象的狀態.

5、元數據允許垃圾回收器跟蹤對象生存期,垃圾回收器能判斷任何對象的類型,並從元數據中知道那個對象的哪個字段引用了那個類型.

 

 

Microsoft的C#、Visual Basic,F#和IL匯編器總是生成包含托管代碼(IL)和托管數據(可進行垃圾回收的數據類型)的模塊。為了執行包含托管代碼以及/或者托管數據的模塊,最終用戶必須在自己的電腦上安裝CLR(目前作為.Net Framework的一部分提供)

C++編譯器默認生成包含非托管(native)代碼的EXE/DLL模塊,並在運行時操縱非托管數據(native 內存),這些模塊不需要CLR即可執行,通過命令行開關,C++編譯器就更能生成包含托管代碼的模塊,當然用戶必須安裝CLR才能執行這種代碼,在前面提到的所有的Microsoft編譯器中,Misrosoft C++編譯器是獨一無二的,只有它才允許開發人員同時寫托管代碼和非托管代碼,並生成到同一個模塊中,它也是惟一一個允許開發人員在源代碼中定義托管非托管數據類型的Microsoft編譯器.它的靈活性是其他編譯器無法比擬的,因為它允許開發人員在托管代碼中使用原生C/C++代碼,時機成熟之后在使用托管類型.

 


免責聲明!

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



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