標籤:

C#的編譯過程

C#的編譯過程

圖解:

圖一

csc.exe

說明:csc.exe是專門針對c#的編譯器,輸入文件是cs文件,而MSBuild.exe是VS的編輯器,可以編譯各種VS工程,比如C++工程

MSBuild.exe是VS的編輯器===》MSBuild是一個生成應用程序的平台

參考文檔:

  • csc:

使用 csc.exe 實現命令行生成?

docs.microsoft.com圖標

  • MSBuild:

MSBuild?

docs.microsoft.com圖標

使用樣例:

  • 編譯生成DLL:csc -target:library File.cs
  • 編譯生成EXE:csc -out:My.exe File.cs
  • 將當前目錄下所有C#文件編譯生成DLL文件:csc -target:library -out:Something.xyz *.cs

CLR

.NET FrameWork的核心是其運行庫執行環境,稱為公共語言運行庫(Common Language Runtime)。

作用:

  • CLR是一個類似於JVM的虛擬機,為微軟的.Net產品提供運行環境。
  • CLR上實際運行的並不是我們通常所用的編程語言(例如C#、VB等),而是一種位元組碼形態的「中間語 言」。這意味著只要能將代碼編譯成這種特定的「中間語言」(MSIL),
  • 任何語言的產品都能運行在CLR上。
  • CLR通常被運行在Windows系統上,但是也有一些非Windows的版本。這意味著.Net也很容易實現「跨平台」。(至於為什麼大家的印象中.Net的跨平台性不如Java,更多的是微軟商業戰略導致的)。

語言支持:

微軟已經為多種語言開發了基於CLR的編譯器,這些語言包括:C++/CLI、C#、Visual Basic、F#、Iron Python、 Iron Ruby和IL。除此之外,其他的一些公司和大學等機構也位一些語言開發了基於CLR的編譯器,例如Ada、APL、Caml、COBOL、Eiffel、Forth、Fortran、Haskell、Lexicon、LISP、LOGO、Lua、Mercury、ML、Mondrian、Oberon、Pascal、Perl、PHP、Prolog、RPG、Scheme、Smaltak、Tcl/Tk。

CLR為不同的編程語言提供了統一的運行平台,在很大程度上對上層開發者屏蔽了語言之間才特性差異。對於CLR來說,不同語言的編譯器(Compiler)就相當於一個這種語言的代碼審查者(Checker),所做的工作就是檢查源碼語法是否正確,然後將源碼編譯成CLR所需要的中間語言(IL)。所以編程語言對於CLR是透明的,也就是說CLR只知道IL的存在,而不知道IL是由哪種語言編譯而來。

功能

(1)基類庫支持 (Base Class Library Support)

(2)內存管理 (Memory Management)

(3)線程管理 (Thread Management)

(4)垃圾回收 (Garbage Collection)

(5)安全性 (Security)

(6)類型檢查 (Type Checker)

(7)異常處理 (Exception Manager)

(8)即使編譯 (JIT)

託管模塊

託管模塊是標準的32位Windows可移植執行體(PE32)文件,或者是標準的64位Windows可移植執行體(PE32+)文件,它們都需要CLR才能執行。

託管模塊包括:PE32或PE32+頭、CLR頭、元數據和IL(中間語言)代碼。 下圖為各個部分的說明:

圖二

MSIL/託管代碼

中間語言(Microsoft Intermediate Language MSIL)代碼, 這些代碼並非專門用於任何一種操作系統, 也非專門用於C#,稱為託管代碼。

編譯器把代碼編譯成中間語言(IL),而不是能直接在你的電腦上運行的機器碼。中間語言(IL)在公共語言運行庫(CLR)中運行,這個運行庫給你的運行代碼提供各種各樣的服務(如內存管理和類型檢查)。 .NET和C#只能產生託管代碼。如果你用這類語言寫程序,那麼所產生的代碼就是託管代碼。

優點

中間語言代碼與Java位元組碼共享一種理念:它們都是低級語言,語法很簡單(使用數字代碼,而不是文本代碼),可以非常快速地轉換為本地機器碼。對於代碼,這種精心設計的通用語法有很重要的優點:平台無關性、提高性能和語言的互操作性。

2.2 非託管代碼

非託管代碼就是在Visual Studio .NET 2002發布之前所創建的代碼。例如Visual Basic 6, Visual C++ 6, 最糟糕的是,連那些依然殘存在你的硬碟中、擁有超過15年歷史的陳舊C編譯器所產生的代碼都是非託管代碼。

非託管代碼直接編譯成目標計算機的機械碼,這些代碼只能運行在編譯出它們的計算機上,或者是其它相同處理器或者幾乎一樣處理器的計算機上。非託管代碼不能享受一些運行庫所提供的服務,例如安全和內存管理等。如果非託管代碼需要進行內存管理等服務,就必須顯式地調用操作系統的介面,通常來說,它們會調用Windows SDK所提供的API來實現。

跟Visual Studio平台的其他編程語言不一樣,Visual C++可以創建非託管程序。當你創建一個項目,並且選擇名字以MFC,ATL或者Win32開頭的項目類型,那麼這個項目所產生的就是非託管程序。

兩者之間的區別:

a. 託管代碼是一種中間語言,運行在CLR上;

a. 非託管代碼被編譯為機器碼,運行在機器上。

b. 託管代碼獨立於平台和語言,能更好的實現不同語言平台之間的兼容;

b. 非託管代碼依賴於平台和語言。

c. 託管代碼可享受CLR提供的服務(如安全檢測、垃圾回收等),不需要自己完成這些操作;

c. 非託管代碼需要自己提供安全檢測、垃圾回收等操作。

元數據

元數據概述:元數據是一種二進位信息,用以對存儲在公共語言運行庫可移植可執行文件 (PE) 文件或存儲在內存中的程序進行描述。將您的代碼編譯為 PE 文件時,便會將元數據插入到該文件的一部分中,而將代碼轉換為 Microsoft

中間語言 (MSIL)

並將其插入到該文件的另一部分中。在模塊或程序集中定義和引用的每個類型和成員都將在元數據中進行說明。當執行代碼時,運行庫將元數據載入到內存中,並引用它來發現有關代碼的類、成員、繼承等信息。

元數據以非特定語言的方式描述在代碼中定義的每一類型和成員。元數據存儲以下信息:

(1)程序集的說明

標識(名稱、版本、區域性、公鑰)。

導出的類型。

該程序集所依賴的其他程序集。

運行所需的安全許可權。

(2)類型的說明

名稱、可見性、基類和實現的介面。

成員(方法、欄位、屬性、事件、嵌套的類型)。

(3)屬性

修飾類型和成員的其他說明性元素。

參考博客:

C#程序的編譯過程 - 葉丶梓軒 - 博客園?

www.cnblogs.com圖標https://blog.csdn.net/stive_sourcexin/article/details/51329697?

blog.csdn.net

https://blog.csdn.net/u013905744/article/details/46591619?

blog.csdn.net


推薦閱讀:

怎樣用C++實現生產者消費者的模擬?
C++ 中的 std::map 不同線程操作不同 key 是否需要加鎖?
關於googletest裡面的一個小問題,求高手解決?
C++11(VC++) 中支持多種for循環寫法,哪種比較好?
double 和 long double 有哪些區別?

TAG:編譯器 | 編譯 | C |