C#基礎知識梳理系列一:CLR及程式集部署

來源:互聯網
上載者:User
摘 要

.NET Framework 到底是什嗎?通用語言執行平台和 .NET Framework 類庫分別指的是什麼東西?CLR、 CLS、 CTS、FCL等這些又是什嗎?為什麼出現程式集的概念?它與動態連結程式庫的區別是什嗎?什麼是強命名程式集?如何簽名及部署程式集?這一章將協助您學習和瞭解其中的秘密。

第一節 .NET Framework是什嗎?

.NET Framework(.NET架構),是由微軟提出並實施的一個整合在Windows中的組件。它基於虛擬機器技術實現的平台無關性的軟體開發平台,它以語言運行庫(CLR)為平台支援多種語言開發,如C#、VB、託管C++等,以強制的型別安全為基礎實施運行在託管環境中來達到代碼安全和隔離運行、提供對記憶體的自動化管理、線程的最佳化切換、提供一個統一的物件導向編程模型。

.NET Framework環境

版本發布曆史:

版本 完整版本號碼 發行日期 Visual Studio
1.0 1.0.3705.0 2002-02-13 Visual Studio .NET 2002
1.1 1.1.4322.573 2003-04-24 Visual Studio .NET 2003
2.0 2.0.50727.42 2005-11-07 Visual Studio 2005
3.0 3.0.4506.30 2006-11-06  
3.5 3.5.21022.8 2007-11-19 Visual Studio 2008
4.0 4.0.30319.1 2010-04-12 Visual Studio 2010
4.5 4.5.40805 2012-02-20 Visual Studio 2012 RC

MSDN .NET Framework描述

.NET Framework 包含兩大核心組件:通用語言執行平台和.NET Framework類庫。

第二節 通用語言執行平台

通用語言執行平台 英文名Common Language Runtime,簡稱 CLR。它是一個相對開放的運行平台,可供多種語言(C#、VB等)使用的運行時。CLR擁有一組核心功能,包括:記憶體管理、線程執行、程式集載入、異常處理、強制型別安全等,這些功能對所有面向CLR的語言都支援。在程式啟動並執行時候,CLR對編碼語言是未知的,無論任何語言,只要它的編譯器是面向CLR的就可以。像微軟自己的C#編譯器、VB編譯器、F#編譯器等。當然你也可以實現自己的編譯器,但你的編譯器必須是面向CLR的。編譯器將對原始碼進行語法驗證和分析,最終產生託管模組(Managed Module),進而一個傳說中的程式集誕生了。

託管模組 是一個標準Microsoft Windows可移植執行體,它可能是32位(PE32)檔案,也可能是64位(PE32+)檔案。託管模組有如下幾部分組成:

PE32/PE32+ 頭 標準的 Windows PE檔案頭。如果檔案頭使用PE32格式,則此檔案只能在Windows 的32位或64位版本上運行;如果檔案頭使用PE32+格式,則此檔案只能在Windows 的64位版本上運行。另外,檔案頭還可能包含與本地CPU代碼相關的資訊。編譯器在編譯時間,可通過編譯平台/platform開關來指定該程式集包含一個PE32頭或PE32+頭。在Visual Studio中可以對目標平台進行選擇,

CLR頭 包含了標誌此模組為一個託管模組的基本資料,如CLR版本、託管模組入口方法、模組的中繼資料、資源等。

中繼資料 中繼資料是一組資料表,它是一個二進位塊。包含三類資料表:一個表描述了與此模組對應的原始碼中定義的類型、成員,這是定義表;另一個表描述了此代碼所引用的其他類型(成員)列表,這是參考資料表,還有一類是清單表。常見的中繼資料定義表有ModuleDef、TypeDef、MethodDef、FieldDef、ParamDef、PropertyDef、EventDef。常見的參考資料表有AssemblyRef、ModuleRef、TypeRef、MemberRef。

IL代碼 也是中繼語言。編譯器編譯原始碼時產生的中間代碼,在執行環境中,這些IL代碼將被CLR的JIT編輯器翻譯成CPU能識別的指令,供CPU執行。

在執行時,CLR是通過程式集與託管模組進行溝通的。程式集是一個或多個託管模組和資源檔的邏輯分組,(它就相當於一個省份組織,它劃分了一部分人和地區資源)。程式集是由編譯器產生,最終產生的可能是EXE或DLL檔案。在程式集內有一個清單,其描述了程式集內的檔案清單,如託管模組、jpeg檔案、XML檔案等。CLR能夠通過程式集內模組中的自描述資訊來確定要執行此程式集中代碼時所依賴的其他對象。

動態連結程式庫(Dynamic-Link Libraries,簡稱DLLs),就是一個可執行模組,其副檔名為.dll,它是基於C++,Delphi等語言產生的。模組中包含了可以被其他應用程式或其他dll使用的常式和資源。dll沒有通常的主程式,但它有多個執行入口。DLLs的特點在於它的代碼是在運行期動態地連結到調用它的程式中的。

.NET Framework中的 程式集的副檔名dll與動態連結程式庫中的dll無非是同名罷了,是完全不相同的兩個概念。

下面以一個控制台程式來類比CLR載入及程式運行過程。範例程式碼:

View Code

1 class Program 2  { 3         static void Main(string[] args)4  { 5             System.Diagnostics.Debug.WriteLine("hello world");                 6             System.Diagnostics.Debug.WriteLine("hello c#"); 7                             } 8     }

(1)在Windows中要運行一個EXE檔案,Windows會首先檢查這個EXE檔案的頭,以確定該檔案是32位、64位還是WoW64(Windows on Windows64技術,運行32位程式運行在64位版本的Windows環境中),進而建立相應的進程,然後在進程的地址空間中載入MSCorEE.dll的相應x86、x64、IA64版,緊接著進程的主線程調用MSCorEE.dll中的一個CorBindToRuntimeEx函數,這個函數的主要功能就是載入CLR。CorBindToRuntimeEx函數定義:

HRESULT CorBindToRuntimeEx (
[in] LPWSTR pwszVersion,
[in] LPWSTR pwszBuildFlavor,

[in] DWORD startupFlags,

[in] REFCLSID rclsid,

[in] REFIID riid,

[out] LPVOID* ppv

);

pwszVersion 描述要載入的 CLR 的版本。
pwszBuildFlavor 字串,指定是載入 CLR 的伺服器版本還是工作站版本。值:svr 和 wks。
startupFlags。STARTUP_FLAGS 枚舉值的組合。這些標誌控制並發記憶體回收、非特定於域的代碼以及 pwszVersion 參數的行為。如果未設定標誌,則預設值為一個域。
rclsid 實現ICorRuntimeHost 介面的 coclass 的 CLSID。支援的值為 CLSID_CorRuntimeHost或 CLSID_CLRRuntimeHost。
Riid 請求自 rclsid 介面的 IID。支援的值為 IID_ICorRuntimeHost 或 IID_ICLRRuntimeHost。
Ppv 返回的指向 riid 的介面指標。

(2)CLR載入完成後,在執行Main方法前CLR會檢查Main 方法所引用的所有類型且在內部初始化一個資料結構來記錄被參考型別的內的每個方法的入口。由於程式集內包含了中繼資料和IL,接下來CLR的主要工作就是要先找到WriteLine方法的IL,用JIT編譯器對其進行驗證(Verification),把IL翻譯成本地CPU指令,指令被儲存在動態記憶體中。接著進行壓棧,執行第一個WriteLine方法。如果下次要再次執行WriteLine方法,由於第一次已經對該方法進行驗證及編譯(CPU指令),所以這次直接執行CPU指令即可。所以一個類型或方法,只有在第一次執行時有效能損失,以後對該類型的調用是直接運行CPU指令,效能飛速提高。

第三節 .NET Framework類庫

Framework 類庫 英文名 Framework Class Library 簡稱 FCL。是一組與CLR緊密整合的可重用的物件導向的類型(程式集)集合。它包含有成千上萬個能使我們的Managed 程式碼從中匯出的類型。它不僅提供了一些常見的編程功能,如字串處理,資料庫連接等,還提供了一些進階開發,如線程同步,反射,記憶體回收等功能;它不僅公開了一些UI庫,如Windows
from 、Web表單、Silverlight等,還公開了一些面向服務的編程,如WebService,、Windows 服務、WCF等。

由於類庫提供了太多的類型,所以它們以命名空間為組織劃分到不同的dll中。例如:

System命名空間 包含了每個應用程式都要用到的所有基本類型。

System.IO命名空間 包含了執行流I/O 以及瀏覽目錄的類型等。

基底類別庫 英文名 Base Class Library 簡稱BCL。它封裝了大量的基礎功能,如檔案操作、圖形操作、網路連接、XML文檔解析、安全加密,等等。

第四節 一般型別系統

由於在執行時CLR對它支援的語言未知,(當然,這些語言必須是面向CLR)即CLR不管要執行的代碼是 C# 編寫還是VB編寫。CLR圍繞類型展開,只要其編碼語言是面向CLR的,它們就可以相互交流,要想達到相互認識和理解,必須制定類型的定義和行為及狀態。這個對類型的定義和行為的描述就是一般型別系統。英文名Common
Type System 簡稱CTS。

CTS規定一個類型可以包含零個或多個成員,這些成員包括:欄位,屬性,方法,事件等,另外還可以對成員的訪問規則進行控制,如public ,private,internal等。

第五節 通用語言規範

Common Language Specification 英文名Common Lahguage Specification 簡稱 CLS。

CLR整合支援了所有面向CLR的語言,允許在一種語言中使用另一種語言建立的對象,但由於各種語言本身的特性,比如有些語言不支援不帶正負號的整數,有些不區分大小寫。如果要想做到自己公開的類型能被其他語言所識別,則就要儘可能按照其他語言所支援的特性且自己也支援的特性去構造。CLS詳細定義了一個各種面向CLR共有的最小功能集。

第六節 通用語言基礎架構

通用語言基礎架構(Common Language Infrastructure,簡稱CLI)是一個開放的技術規範。維基百科解釋:定義了構成.NET Framework基礎結構的可執行碼以及代碼的運行時環境的規範,它定義了一個語言無關的跨體繫結構的運行環境,這使得開發人員可以用規範內定義的各種進階語言來開發軟體,並且無需修正即可將軟體運行在不同的電腦體繫結構上。

CLI有時候會和CLR混用。但嚴格意義上說,這是錯誤的。因為CLI是一種規範,而CLR則是對這種規範的一個實現。

 

第七節 強命名程式集及部署

在經過編譯器產生程式集後,如果只是一個應用程式使用該程式集,則直接將該程式集複製到目標目錄即可,這就是私用組件的部署。如果一個程式集有多個程式使用,則需要把這個共用的程式集放到一個公用的目錄。像全域應用程式定義域裡的程式集就是公用的。但是,如果有多個部門或公司開發的具有相同名稱的程式集放到同一個目錄,這就可能不太現實,因為後來部署上去的DLL會覆蓋先前一次部署的DLL,很顯然以檔案名稱來區分程式集是不可取的。CLR必須提供對程式集進行唯一性驗證辦法。這就是“強命名程式集”。一個強命名程式集用四個屬性共同對一個程式集進行標識,這四個屬性是:檔案名稱(不包括副檔名)、版本號碼、語言文化特性和一個公開金鑰(使用公開金鑰派生出的一個小的Hash
值,公開金鑰標記)。如下一個組件檔:

“commonTypes,Version=2.0.2.1029,Culture=neutral,PublicKeyToken=c55b39c999a8888d”

強命名程式集可以防被篡改,也可以將強命名程式集部署到全域組件快取。

(1)使用SN產生密鑰,命令列導航到VS安裝目錄,使用SN命令即可產生一個密鑰,如下:

(2)將已經產生的MyApp.snk複製到項目工程下,如,當然也可以放到其他目錄:

(3) 設定項目的屬性簽名

(4) 重建項目即可得到具有強命名的程式集。

(5) 如果一個程式集是由多個應用程式使用,必須把它部署到一個讓CLR能檢測到的已知目錄,那這個目錄就是全域組件快取GAC。.NET4.0的GAC位於:

C:\Windows\Microsoft.NET\Assembly

必須使用GACUtil.exe工具來完成程式集的部署工作。該命令有兩個重要的開關:

/i 將某個程式集安裝到全域組件快取中

/u 將某個程式集從全域組件快取中卸載

安裝樣本:

gacutil /i 強命名程式所在的絕對路徑

例如:D:\>gacutil /i C:\MyApp.dll

除了將強命名程式集部署到GAC以外,還可以以私人方式部署程式集,例如將其部署到網路上,在config中配置當程式運行時再載入該程式集。如:

<codeBase                version="2.0.0.0" href="http://www.roojune.com/MyApp.dll"/>
小 結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.