編譯原始碼為託管模組

來源:互聯網
上載者:User

非託管 C/C++可以在底層控制系統,能精確地按照自己的需要來管理記憶體, 很容易建立線程等等.VB6允許你快速地構建UI應用程式,很容易控制COM對象和資料庫.

CLR正像其名字那樣, runtime被很多不同的程式設計語言使用, CLR的feature對任何以CLR為目標的程式設計語言都是使用的.例如, runtime使用異常來報告錯誤, 因此所有的語言都是通過異常來報告錯誤的. 另外一個例子是runtime允許你建立一個線程,因此所有的語言都可以建立線程.

實際上, 在runtime時, CLR並不知道開發人員使用了什麼程式設計語言, 這意味著你應該選擇更容易表達你的目的程式設計語言, 只要你使用的編譯器是以CLR為目標的.

所以, 如果我說的是正確的話, 那麼使用一種語言比另一種語言的先進之處是什麼呢? 我把編譯器看作是語法檢查器或者代碼糾正分析器, 它們檢查你的原始碼, 確保你寫的代碼有意義, 然後輸出表達你的意願的代碼. 不同的程式設計語言允許你用不同的文法開發, 不要低估這種選擇的價值,對於數學或者商業上的應用程式, 和使用Perl文法相比, 使用APL文法來表達你的意願能夠節約不少開發的時間.

微軟已經建立了幾個語言編譯器(以runtime為目標的): C++/CLI, C#, VB, Jscript, J#和一個中繼語言(IL)彙編器. 除了微軟, 一些其他公司, 大學也建立了以CLR為目標的編譯器. 我注意到的編譯器有Ada, APL, Caml, COBOL, Eiffel, Forth, Fortran, Haskell, Lexico, LISP, LOGO, Lua, Mercury, ML, Mondrian, Oberon, Pascal, Perl, Php, Prolog, Python, RPG, Scheme, Smalltalk, Tcl/Tk.

給出了編譯原檔案的過程, 可以看出,你可以用支援CLR的任何程式設計語言建立原檔案, 然後你使用對應的編譯器來檢查文法和分析原始碼. 不管你使用什麼編譯器, 編譯的結構都是託管模組. 一個託管模組是一個標準的32-bit微軟Windows portable executable (PE32) 檔案或者標準的64-bit Windows portable executable (PE32+) 檔案, 它們需要CLR來執行。

下表描述了託管模組的各個部分:

各個部分

描述

PE32 or PE32+ header

標準的Windows PE檔案頭, 它和Common Object File Format (COFF) header相似. 如果使用PE32格式, 那麼檔案將運行在32-bit或者64-bit版本的Windows上. 如果使用PE32+格式, 檔案需要64-bit版本的Windows來運行. 這個頭也指明了檔案的類型: GUI, CUI 或者 DLL, 還包含著時間戳記資訊來表明檔案構建的時間. 對於只包含IL代碼的mudule, 該資訊塊被忽略. 對於包含native CPU代碼的模組, 這個header包含了關於native CPU代碼的資訊.

CLR header

包含著使其成為託管模組的資訊. 這個header包含了需要CLR的版本, 一些標誌, 託管模組的入口方法(main方法)的MethodDef metadata符號, 和matadata, 資源, strong name, 標誌, 和其它不太有意義成員的位置/大小.

Metadata

每個託管模組都包含著metadata表, 有兩類主要的表: 描述你的原始碼中的類型和成員的表, 描述你的原始碼所引用的類型和成員的表.

IL code

編譯器編譯元代碼所產生的代碼, 在runtime時, CLR將編譯IL為native CPU指令.

Native代碼編譯器產生的代碼是針對特定的CPU架構的, 例如x86, x64或者IA64. 所有的CLR相容的編譯器都產生中繼語言(IL)代碼, IL代碼有時候也稱為Managed 程式碼, 因為CLR管理它的執行過程.

除了產生IL, 每個以CLR為目標的編譯器都要為每個託管模組產生完整的metadata. 簡單地說, metadata是一組資料表格, 其描述了模組中定義的內容, 例如類型和它們的成員. 此外, metadata還包括它所管理的模組引用, 例如匯入的類型和它們的成員. Metadata是原有技術(例如類型庫Type Library和介面定義語言IDL檔案)的超集. 要注意的重要事情是CLR metadata的資訊更加完整. 不像類型庫和IDL, metadata總是和包含IL代碼的檔案相關聯. 實際上, metadata總是作為代碼嵌入相同的EXE/DLL中, 使得很難將其分離出來. 因為編譯器是同時產生metedata和代碼, 並將它們綁定到最終的託管模組, metadata和它所描述的IL代碼永遠都不需要互相同步.

Metadata有很多用途, 下面是其中的一些:

  1.    Metadata去掉了編譯時間需要的標頭檔和庫檔案, 因為關於引用的類型/成員的所有的資訊都包含在IL所在檔案中(IL實現了這些類型/成員). 編譯器能從託管模組中直接讀取metadata.
  2.    微軟Visual Studio使用metadata來協助你寫代碼, 它的智能感知feature解析metadata, 告訴你一個類型所提供的方法, 屬性, 事件, 和欄位, 對於一個方法, 告訴你方法所需要的參數.
  3.    CLR代碼驗證過程使用metadata來確保你的代碼只執行”安全”的操作.
  4.    Metadata允許一個對象的欄位被序列化(serialize)到一個記憶體塊中, 將其發送給另外一台機器, 然後在遠程機器上還原序列化(deserialize), 重新建立對象的狀態.
  5.    Metadata允許記憶體回收行程跟蹤對象的剩餘時間. 對於任何一個對象, 記憶體回收行程可以確定對象的類型, 知道對象中的哪個欄位引用了其它對象.

微軟的C#, VB, JScript, J#和IL彙編器總是產生包含Managed 程式碼 (IL)和託管 data (記憶體回收的資料類型)的模組. 終端使用者必須安裝CLR (目前是作為.NET Framework的一部分發布的), 來執行包含Managed 程式碼和/或管理的資料的模組. 這和運行MFC或者VB6應用程式所需要的MFC類庫或者VB DLL一樣.

預設地, 微軟的C++編譯器build的EXE/DLL模組只包含Unmanaged 程式碼和資料. 這些模組不需要CLR就能執行. 然而, 通過指定/CLR命令列開關, C++編譯器可以產生包含Managed 程式碼的模組, 當然必須安裝CLR才能執行代碼. 上面所提到的所有的微軟編譯器中, C++是最特殊的, 因為它是唯一的編譯器允許開發人員既能寫Managed 程式碼, 也能寫非託管的代碼, 並將它們放到一個模組中. 也只有微軟的編譯器才能允許開發人員在他們的原始碼中既能定義託管的資料類型, 也能定義非託管的資料類型. 微軟C++編譯器所提供的靈活性遠超過其它的編譯器, 因為它允許開發人員用Managed 程式碼編寫應用程式, 然後在非託管的C++代碼中訪問它們.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.