C++ 託管擴展 (Managed Extensions for C++)
對Microsoft Visual C++語言進行擴展可以生成.NET代碼,這些擴展稱為C++.NET託管擴展。C++是惟一一種可以在同一個源檔案中混合.NET代碼和非託管代碼的語言,是真正的.NET系統語言。
C++引入託管擴展的原因是既可以保持與原有C++特性的充分兼容;又可以提供足夠的對.NET套用開發的支持
託管C++應用程式開發之概述
1、什麼是託管C++
.Net環境提供了許多核心的運行(RUNTIME)服務,比如異常處理和安全策略。為了能使用這些服務,必須要給運行環境提供一些信息代碼(元數據),這種代碼就是託管代碼。所有的C#、VB.NET、JScript.NET默認時都是託管的,但Visual C++默認時不是託管的,必須在編譯器中使用命令行選項(/CLR)才能產生託管代碼。
與託管代碼密切相關的是託管數據。託管數據是由公共語言運行的垃圾回收器進行分配和釋放的數據。默認情況下,C#、Visual Basic 和 JScript.NET 數據是託管數據。不過,通過使用特殊的關鍵字,C# 數據可以被標記為非託管數據。Visual C++數據在默認情況下是非託管數據,即使在使用 /CLR 開關時也不是託管的。
託管類
儘管Visual C++數據在默認情況下是非託管數據,但是在使用C++的託管擴展時,可以使用“__gc”關鍵字將類標記為託管類。就像該名稱所顯示的那樣,它表示類實例的記憶體由垃圾回收器管理。另外,一個託管類也完全可以成為 .NET 框架的成員,由此可以帶來的好處是,它可以與其他語言編寫的類正確地進行相互操作,如託管的C++類可以從Visual Basic類繼承等。但同時也有一些限制,如託管類只能從一個基類繼承等。
需要說明的是,在託管C++應用程式中既可使用託管類也可以使用非託管類。
在託管C++中,託管類和非託管類是可以相互使用各自的特徵,但託管類能夠封裝.NET框架中的組件,且最大限度地使用.NET框架中的特性,而傳統的C++類是使用MFC和ATL來設計的,用來編制基於Windows環境的應用程式。
2、為什麼使用託管C++
除了可以充分發揮.NET框架新特性外,使用託管C++還有下列好處:
(1) 由於在同一個應用程式中,甚至是同一個檔案中,我們可以同時使用託管C++和傳統的非託管C++來編寫,因而我們可以充分利用兩種C++所帶來的好處,並且可將代碼和組件快速移植到.NET框架中。
(2) 使用託管可以從任何一個.NET框架兼容語言中調用一個C++組件,也可調用非託管DLL、其它庫以及類等。
(3) 可以直接從非託管代碼中訪問.NET框架。
總而言之,使用託管C++是C++程式設計師編寫.NET框架應用程式最好的一種選擇,在充分理解.NET框架基礎上,避免了使用其他語言如C#、VB.NET所帶來的額外開銷。
為什麼使用C++託管擴展
在整個Visual Studio開發套件中,微軟為了迎合.NET應用程式開發模式的要求,幾乎對每個工具都作了或大或小的改進。其中,VB的變革力度套用微軟各種軟體產品之最。但是太大的變革往往會帶來兼容性問題,特別是新版本的VB宣稱其只能開發託管的應用程式(也就是.NET應用程式),所以對開發人員來講,這肯定意味著過去使用VB編寫的代碼在新版本VB上進行重新構造的難度會很大。VB以前就在版本兼容性方面有著不如人意的歷史—— 在VB4、VB5、VB6之間進行升級,會讓開發人員付出很多辛苦。現在,由於VB的體系進行了很大的改動,所以版本兼容性問題會更嚴重一些—— 筆者已經在微軟幾個官方討論組中看到了一些開發人員和相關人士對此表示出來的擔憂,並看到不止一個開發人員對新版本VB在兼容性方面存在問題提出質疑甚至是批評。
作為微軟開發套件中的另一位“元老”—— Visual C++,我們對其提供完整的.NET開發支持感到高興的同時也同樣擔心它的版本兼容性問題—— Visual C++該不會也和VB一樣,徹底與MFC和ATL分裂吧?答案是:不可能!
這是一個令人振奮的回答,下面就讓我們花一點時間來了解新版本Visual C++是怎樣處理變革和向下兼容之間的關係的。
另外,之所以微軟對VB進行那樣大的改革,是因為微軟認為VB通常適用於快速應用程式領域,這些領域一般包含對效率要求不是很高的資料庫前端應用程式或後端業務組件。當更為優秀的.NET框架發布之後,微軟就為VB換了換“心臟”,以期大幅度增強VB的功能,使之成為快速開發.NET應用程式的主力軍。而對於Visual C++這樣一個在許多傳統領域依然寶刀不老的工具,當然不能急躁冒進,將已有的功能丟棄。所以,在新版本的Visual C++中,採用了一種更為折衷的方法—— 擴展現有C++語言,讓Visual C++在編寫純粹的.NET應用程式的同時,依然可以利用其成熟的技術進行未託管的應用程式的開發。
C++託管擴展是一個對現行C++語言進行擴展的集合,這個集合可以幫助Visual C++的開發人員編寫.NET Framework應用程式。由於是對語言做了擴展,而不是徹底去掉原先C++語言的功能,所以在託管擴展中,開發人員可以在同一個應用程式中混合使用傳統未託管的代碼和新型的託管的代碼。這樣做得到的一個直接好處是,應用程式既可以享受未託管的代碼特性也可以享受託管的代碼特性。對組件開發也是一樣,傳統組件可以很容易被包裝(wrapper)成.NET 框架組件,充分保障已有工作的投資。
在實際工作中,如果開發人員遇到下列開發需求,使用託管擴展將是最佳選擇:
● 需要快速地將未託管的C++應用程式合併到.NET框架中
對於以前開發的傳統未託管的C++應用程式,因為開發人員可以在同一個應用程式中(甚至是在同一個檔案中)混合使用兩種類型的代碼,所以託管擴展為實現兩種代碼的無縫轉化提供了一種平滑的轉化方式。
開發人員可以繼續使用未託管的C++來編寫組件,以利用語言本身強大的功能和靈活性。然後,為了讓.NET 框架應用程式順利訪問這個傳統組件,開發人員可以使用託管擴展編寫一個很小的、轉換效率很高的包裝(wrapper)程式。
● 需要讓任何一種與.NET框架相容的語言可以訪問C++組件
託管擴展支持從任何.NET 框架相容語言來調用C++類。調用之所以可以實現,是因為使用託管擴展可以編寫簡單的包裝類來對訪問方暴露對應的C++類和方法。這些包裝類都是託管的,並可以從其他.NET框架相容程式中進行調用。在調用過程中,外包類在託管的類和未託管的類之間扮演了映射層的角色—— 它讓方法調用直接傳遞到未託管的類中。另外,需要特別指出的是,託管擴展支持對任何未託管的DLL或庫的調用。
● 需要從未託管的代碼中訪問.NET框架類
為了得到更多的功能,在未託管的代碼中,可以訪問.NET 框架中的類。使用託管擴展,可以從C++代碼中直接創建、調用一個.NET 框架類。在實際編程中,可以像處理普通未託管的C++類一樣對待對託管的類的處理。另外,在.NET框架中提供了對未託管的COM的調用支持,可以編寫未託管的代碼直接訪問。
因為託管的代碼和未託管的代碼各有優點,在實際工作中,開發人員可以根據項目的實際情況,靈活選擇兩者的使用。在某些追求訪問效率的情況下,通過.NET 框架提供的COM接口進行訪問可以收到比較好的運行效果;而在某些需要快速完成任務的情況下,利用.NET 框架提供的簡便性進行工作會讓開發人員倍感輕鬆。
託管C++並非獨立存在的程式語言,而僅僅是微軟對C++的一個語法擴展,允許C++程式設計師在.NET框架和CLR的基礎上進行託管編程。與C#和Visual Basic .NET相比,其主要優點是舊代碼可以比較快地移植到新的平台上,而且即使不完全重寫代碼,也可以通過互操作在同一個模組中無縫整合託管和非託管代碼,從新的.Net框架中獲益。.Net框架封裝了大量的API,例如網路訪問、字元串操作、數據訪問、XML服務、圖形界面控制項庫、郵件服務、加密服務、檔案輸入/輸出,甚至是WMI管理,也使得套用程式設計師可以編寫更加簡潔的代碼。目前只有託管C++及其後繼者C++/CLI可以做到無縫整合託管和非託管代碼,而在託管代碼中調用COM的速度又相當慢,所以經常被用於其他語言和非託管代碼之間的橋樑。