.Net 從代碼生成到執行,這中間的一些列過程是一個有別于其他的新技術新概念,那么這是一個什么樣的過程呢,有什么樣的機制呢,清楚了這些基本的東西我們做.Net的東西方可心中有數。那么,CLR的執行模型是一個什么樣的過程呢?
將源代碼編譯成托管模塊 --> 將托管模塊合并成程序集 --> 加載公共語言運行時 --> 執行程序集的代碼
首先.Net開發是支持多語言選擇或者混合語言編程的,代碼的編譯是采用編譯器面向CLR的機制,即,無論何種語言編寫的代碼,只要采用的編譯器是面向CLR的就可以了。
Common Language Runtime:公共語言運行時,可由多種編程語言使用的"運行時"。CLR的核心功能(比如內存管理,程序集加載,安全性,異常處理和線程同步)可由面向CLR的所有語言使用。
Managed module:托管模塊,即編譯器編譯的結果都是一個托管模塊。
IL:每個面向CLR的編譯器生成的都是IL(中間語言)代碼。也成為托管代碼,因為CLR要管理它的執行。
Native code compiler:本地代碼編譯器。生成的是面向特定CPU架構(X86、X64、IA64)的代碼。
Metadata:元數據。是一種數據表,其中一些數據描述了模塊中定義的內容,比如類型和成員;還有些數據描述了模塊引用的內容,比如導入的類型及其成員。元數據總是和包含IL代碼的文件關聯,永遠是同步的。
上圖顯示了托管模塊合并成程序集的過程。
程序集(assembly)的理解:一個或者多個模塊/資源文件的邏輯性分組;程序集是重用、安全性、版本控制的最小單元。
從上圖顯示可看出程序集(assembly)包含一個名為"清單"(manifest)的數據塊,它是由元數據表構成的另一種集合,描述了構成程序集的文件。
另一個地方就是AL.exe:程序集連接器
Windows 檢查EXE文件頭:
PE32:需要32位地址空間,可在32位/64位地址空間中運行
PE32+:需要64位地址空間
CPU架構信息,確保當前CPU是符合要求的
創建32/64/WoW64位進程 :根據exe文件頭創建的
加載MSCorEE.dll: 該文件在C:/Windows/SysWow64 或 C:/Windwos/Sys
看上面的流程還是比較清晰的。
為了執行一個方法,首先必須把它的IL轉換成本地的CPU指令。這是CLR的JIT(just-in-time或者"即時")編譯器的職責。從示意圖來分析其過程是如何的。
JITCompiler 函數調用時,JITCompiler在定義該類型的程序集的元數據中查找被調用方法的IL
-->驗證IL
-->編譯成本地CPU指令
-->返回到剛才的記錄,并修改對JITCompiler的引用,指向剛才編譯的內存塊的地址
-->JITCompiler函數跳轉到剛才的內存塊執行
-->返回到Mian繼續執行
NGen.exe:.NET Framework 提供的工具,可以在一個應用程序安裝到目標計算機上時,將IL代碼編譯成本地代碼。
NGen.exe終于作用:
位置:類似C:/Windows/Microsoft.NET/Framework/v4.0.30319
命令語法:
ngen <action> [options]
ngen /? | /help
FCL:Framework Class Library 是一組DLL程序集的統稱。
CTS:Common Type System,它描述了類型的定義和行為。
CLS:Common Language Specification
相信混合語言的編程才迫使微軟制定了CLS。CLS解決的問題是使用不同的語言創建的對象能夠相互通信。要創建很容易從其他語言中訪問的類型,只能從自己的編程語言中挑選其他語言都確定支持的那些功能。
這就要求任何編譯器生成的類型要想兼容于由其他"符合CLS、面向CLR的語言"所生成的組件,就必須支持這個最小功能集。
告訴編譯器需要檢查CLS兼容性的語法
[assembly:CLSCompliant(true)]
namespace SomeLibrary
{
}
為了迎合之前的非托管代碼的用戶,微軟通過CLR提供了一些機制,允許應用程序中同時包含托管和非托管代碼。
本文還是主要學習了一些.NET平臺設計的一些架構思想和概念,應該在整體上對.NET有一個基本的認識。
新聞熱點
疑難解答