C#程序的編譯過程,如下圖
總結:編譯器將C#代碼編譯成DLL/EXE,DLL/EXE包含metadata(清單數據,對代碼的描述)和IL(中間語言),IL(中間語言)經過CLR/JIT第二次編譯才是機器碼
一,程序的編譯過程,步驟理解
1>C#源文件經過CSC.exe把Visual C#程序代碼編譯成IL文件(這里有很多參數和開關選項,參考 http://blog.chinaunix.net/uid-20715239-id-1219110.html),編譯器編譯生成程序集(exe dll)
2>c#代碼第一次編譯為一種偽代碼稱微軟中間語言(MSIL)和元數據,MSIL和元數據同時儲存在exe或dll 文件中,該偽代碼是獨立於任何CPU 的,所以只要裝有.Net FrameWork的機器均可以運行該偽代碼,這就增強了c#代碼的可移植性。(ps.中間語言IL不是計算機識別語言,此IL文件不能直接被計算機使用)
3>程序執行時,該偽代碼被CLR(Commom Language RunTime)捕獲,CLR激活內部的 JIT(Just in time)編譯器,將偽代碼編譯成針對特定CPU的機器語言,當然該步還要進行類型檢查等,這樣程序就能在任意合理的電腦中運行,得出結果。JIT 的意思為“僅在運行時編譯”,整個代碼的處理過程要編譯兩次。(PS:從IL文件到機器語言,這個工程是機器自動實現的)
二,JIT(即時編輯)又是什么?
1》JIT:即時編譯(Just In-Time compile),這是.NET運行可執行程序的基本方式,也就是在需要運行的時候,才將對應的IL代碼編譯為本機指令。傳入JIT的是IL代碼(第一次編譯生成的代碼),輸出的是本機代碼(機器能識別的代碼),然后把結果保存起來用於將來對同一方法的調用,直到應用程序結束,大大提高了效率,所以部分加密軟件通過掛鈎JIT來進行IL加密,同時又保證程序正常運行。同解釋執行的代碼相比,JIT的執行效率要高很多。
2》,當JIT需要再調用這些已經被編譯好並存儲到代碼緩存中的方法時,它不用再去解釋執行了,而是可以使用代碼緩存中已編譯好的匯編代碼。這能提升你的應用程序的執行效率,因為使用編譯好的代碼要比運行時去解釋要快得多。(PS:JIT將編譯好的代碼儲存在GAC中)
三,GAC是什么?
1》GAC是Global Assembly Cache,全局程序集緩存的簡稱。它解決了幾個程序共享某一個程序集的問題。不必再將那個被共享的程序集拷貝到應用程序目錄了,.NET應用程序在加載的時候,會首先查看全局應用程序集緩存,如果有就可以直接使用,沒有再到應用程序目錄進行查找。
2》GAC還有一個很重要的作用,所有被放入GAC的程序集都是強名程序集,這樣可以保證相同文件名不同版本的程序集被正確的引用,這樣解決了COM時代的DLL地獄問題。同時強名還可以防止程序集偽造。
四,Assembly(程序集)是什么?
1》Assembly是一個包含來程序的名稱,版本號,自我描述,文件關聯關系和文件位置等信息的一個集合。在.net框架中通過Assembly類來支持,該類位於System.Reflection下,物理位置位於:mscorlib.dll。
2》我們可以通過Assembly的信息來獲取程序的類,實例等編程需要用到的信息。
五,編譯流程
六,托管程序集