當寫好了c#的源**後,c#編譯器會把源**編譯成乙個託管模組而非最終的機器語言。這個涉及到clr的相關功能,因為clr就是為了將不同的語言編寫(例如c#、vb)出來的源**可以更好地在不同平台使用,而不是針對某一種架構cpu進行編譯。編譯器編譯出託管模組後,最終通過jit編譯器動態實時編譯託管模組中的il(中間**)**為cpu指令。
回過頭來說託管模組,託管模組主要包含這些資料:元資料、il中間**、clr頭、pe32+頭(32位系統為pe32)
元資料:一種資料表,其中包含著該模組內一些資料。有三種元資料表,分別是定義元資料表、引用元資料表、清單元資料表。定義元資料表的內容為該模組源**中定義的類、字段、方法等資訊,引用元資料表的內容為該模組引用了哪些類、成員等。清單(manifest)則是程式集的乙個必備要求,託管模組都有元資料,但不一定都有清單資料表。當乙個託管模組有了清單之後,它就可以看作是乙個程式集。清單當中記錄著該程式集中的其他檔案的名稱,如下圖用ildasm檢視的乙個程式集的清單內容:
因為我在檔案頭using了很多其他的程式集,所以清單中就會顯示出來我這個程式集引用了那些其他的程式集。除了這些,清單還記錄著一些類似於版本號以及安全資訊的一些內容在末尾。
il中間**:編譯器生成的中間**,之後clr中的jit編譯器會將其翻譯成最終的cpu指令
clr頭:包含使這個模組成為託管模組的資訊,例如一些標誌、託管模組入口方法(main)的元資料token、以及一些其他不重要資料的位置/大小。clr頭在託管模組中並不是很重要,資料大小佔比也是非常小。
pe32+頭:標準的windows pe檔案頭
託管模組的核心內容主要是前面兩個,即元資料以及il中間**。這四種資料組成了託管模組,但clr並不通過託管模組工作,clr通過程式集進行工作。程式集是乙個抽象的概念,它可以看作是乙個或多個託管模組的邏輯性分組。程式集除了託管模組,還包括程式集中需要用到的資源檔案,例如jpg等
程式集一般不是exe就是dll,這倆的區別就是,exe是有自己的程式入口的(main),dll則是功能性比較多,沒有自己的入口。例如在visual studio中,乙個專案就可以看作是乙個程式集。之前提到過託管模組的清單,這裡細說一下多個或者單個模組是如何合併為乙個程式集的。首先,程式集是必須有清單元資料表的,因為清單記錄著程式集的版本、語言文化、發布者等內容,還包括著構成程式集的檔案的描述檔案。
舉個例子,比如我現在有兩個源**檔案在乙個專案裡,分別是rut.cs和fut.cs,分別定義不同的型別與方法,這兩個源**就可以看作是兩個託管模組,字尾是.netmodule(因為編譯器會將源**編譯成託管模組)現在要打包把他們合併成乙個程式集。rut裡的東西不常用,而fut裡的東西常用,所以編譯合併的時候我們就可以把清單元資料放到fut.netmodule中,這樣這兩個託管模組就有了清單,可以看作是乙個程式集,所以fut.netmodule就變為了乙個dll檔案。清單中記錄著程式集中所有檔案的資訊,包括不常用的rut.newmodule。
還有一些其他的形式,比如將清單元資料放到乙個空的託管模組中。最終的dll檔案本身沒有內容,但是其中包含了兩個.netmodule託管模組。
或者程式集中只有乙個託管模組也是可以的,只要這個託管模組有清單。
clr最終將源**程式設計生成程式集,然後對程式集進行執行。所以流程大概就是源**-託管模組-程式集。
CTS,CLS,託管模組,程式集,IL
il可利用所有特性,其他為其子集 cts規範描述型別的定義和行為。cts規定乙個型別可以包含 0個或多個成員。字段,方法,屬性,事件 還定義了型別可見性和訪問型別成員的一些規則 private family assembly等 cts建立了以程式集為型別可見性邊界的規則,而 clr實現了這種可見性規...
PE檔案,程式集,託管模組,元資料
clr實際是和程式集工作,程式集 assembly 是抽象概念 程式集 乙個或多個模組 資源檔案的邏輯性分組,是重用安全性和版本控制的最小單元。編譯器會預設將生成的託管模組生成程式集 程式集既可以是exe,也可以是dll 其中也含有可執行的檔案 元資料是由幾個表構成的二進位制塊,有三種元資料表 定義...
C 之託管模組
託管模組的定義 託管模組是乙個需要clr才能夠執行的標準windows可移植可執行檔案。portalbe executable 簡稱pe 託管模組的生成過程 使用clr支援的程式語言,編寫源 檔案。然後使用該語言的編譯器進行語法分析和語義分析,然後生成託管 託管模組的結構 1.pe表頭的資訊 乙個字...