經常聽到一些剛剛接觸Windows Embedded CE和Windows Mobile開發的人會提出一些疑問。進行Windows Mobile開發,到底使用什麼語言呢?C++還是C#?Java行不行?下面就我自己的想法講述一下Native C++ 和 .NET Compact Framework的異同和選擇。
基于.NET Compact Framework開發的程式,可以叫做托管程式,英文叫做Managed code。所謂Managed code就是使用C#,VB.NET語言來編寫代碼,使用.NET Compact Framework來開發,編譯成平台無關的中間語言(Intermediate Lanuage, IL)的檔案的程式。基于.NET Compact Framework開發的程式,在編寫的時候會使用到.NET Compact Framework 基礎類庫(.NET Compact Framework Base Class Libraries, BCL) ,BCL為應用程式提供API。托管程式在運作的時候會使用到運作時執行引擎(run-time Execution Engine, EE), BCL和EE統稱為Common Language Runtime (CLR)。當托管程式首次執行的時候,CLR會把IL檔案編譯成相關平台的binary檔案(可執行檔案)。這個過程叫做Just-In-Time (JIT) compilation。由于有了這一個過程,是以所有托管代碼都依賴于CLR,是以,需要運作托管代碼的裝置必須安裝 .NET Compact Framework。

圖來自于Windows Embedded CE 6.0 Fundamentals Chapter 9.
上面講述了一堆理論的東西,下面使用一個通俗但不是很貼切的例子講述Native和Managed,Native翻譯成原生,其實有道地的,與生俱來的意思,例如你天生說國語,那麼可以說你是Mandarin Native Speaker。也就是與生俱來說國語,地道地道的國語。如果你要做一些語言相關的産品進行銷售,如果你在銷售産品之前把之翻譯成各個語言,例如在國内銷售翻譯成中文,在美國翻譯成英文,在日本翻譯成日文,這好比你使用Native Code來開發,在編譯時已經為各個硬體平台生成原生的機器代碼。但是Managed(托管)代碼就好比世界語,世界上沒有那個民族和地區天生就說世界語,但是你使用世界語來銷售你的産品。針對每個不同國家和地區,你附送一個及時翻譯機,這個翻譯機會在使用者使用的時候把世界語翻譯成當地原生語言。這就好比基于.NET Compact Framework開發的代碼,需要CLR來翻譯執行。這裡注意不同硬體平台CLR是不一樣的,他們功能都是把IL編譯成Native的機器碼,但是各個平台的機器碼不一樣,是以.NET Compact Framework也不一樣。.NET Compact Framework幫你處理了平台差異性,是以.NET Compact Framework的程式是跨平台的,就像世界語加上翻譯機那樣,基于.NET Compact Framework編寫的代碼可以支援任何平台,前提是微軟為具體平台實作CLR。例如大家都知道Yahoo,其實世界上有一種快要消失的語言就叫做Yahoo,如果你做一個世界語到Yahoo語的翻譯機,那麼你的産品可以不做任何修改就賣到講Yahoo語的地方了。
Native Code
Managed Code
編譯成平台相關的機器碼
編譯成IL(Intermediate Language)
為各個不同裝置編譯不同版本的執行檔案
一次編譯,各種裝置到處運作
不需要其他架構支援(相對于.NET Compact Framework來說)
需要CLR支援,也就是需要安裝.NET Compact Framework Rumtime
可以最大限度的通路系統提供的API和服務
隻能通路.NET Compact Framework 提供的服務,例如WIFI和Bluetooth,.NET Compact Framework 的BCL不提供支援,是以如果隻是使用.NET Compact Framework 是不能進行WIFI和Bluetooth的開發的。
由于有上述的限制性,是以微軟提供P/Invoke來通路平台相關的API和COM。
可以使用MFC,ATL,WTL,STL等庫進行開發
可以使用.NET Compact Framework 的BCL進行開發
了解了Native Code 和 Managed Code的異同,可以根據其特點和相應的需求進行選擇。沒有絕對的好壞,是以才存在兩個平台同時存在的現狀。
Native Code開發速度相對慢一些,因為沒有.NET Compact Framework 的Base Class Libraries的支援。BCL為開發者做了大量的封裝,例如Garbage Collection,Windows form,Web Service等等。基于BCL開發者可以專注于業務的開發。是以使用.NET Compact Framework一般來說可以節省不少開發時間。時至今日,庫對語言的影響越來越多,如果沒有RoR,Ruby可能還是一個籍籍無名的日本方言。C++之父Bjarne Stroustrup說,C++的擴充更多的在STL的擴充,通過STL來支援新特性,以此C++從文法上一直沒有大變化,但是由于STL的不斷擴充而不斷帶來新的活力。可見庫對一個語言和開發人員的重要性。在這方面.NET Compact Framework 勝出,但是Native C++還是可以通過MFC,ATL,WTL,STL來補救。我本人十分喜歡使用WTL處理界面和大量使用STL,關于WTL,可以參考:
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/06/03/Windows_Mobile_WTL.html">Windows Mobile和Wince(Windows Embedded CE)下的WTL(Windows Template Library)開發</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/06/11/Windows_Mobile_WTL_UI.html">Windows Mobile 和 Wince(Windows Embedded CE) 下的 WTL(Windows Template Library) 界面(UI)開發</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/06/30/Windows-Mobile-WTL-Windows-Media-Player.html">Windows Mobile和Wince下使用WTL進行Windows Media Player開發</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/06/30/1513655.html"></a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/07/21/1527677.html"></a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/11/05/Window_Mobile_WTL_Menu.html">Windows Mobile下使用Native C++(WTL, MFC, Win32)開發,如何為對話框加入菜單</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/11/06/Windows_Mobile_WTL_Done_Button.html">Windows Mobile下如何去掉WTL對話框CStdDialogImpl的OK按鈕</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/11/10/Windows_Mobile_WTL_Cursor.html">在Windows Mobile下使用WTL進行Native C++開發,如何顯示等待圖示</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/11/12/Windows-Mobile-WTL-HyperLink.html">在Windows Mobile和Wince(Windows Embedded CE)下進行WTL開發,如何加入超連結(HyperLink)</a>
但是Native Code執行速度相對快,因為基于.NET Compact Framework 的代碼有JIT的過程,第一次執行需要把IL編譯到Native機器碼,而Native Code本身就是機器碼,是以Native Code快很多。
同時Native Code使用的memory footprint也少很多很多,Native Code使用的footprint隻是和你編寫的代碼配置設定記憶體有關。但是基于.NET Compact Framework 的代碼,盡管一個幾乎沒有任何功能的程式,啟動的時候也需要1到2M的記憶體。這些記憶體用于處理Garbage Collection等用途。
Native Code和Managed Code存在一個可控性的gap,.NET Compact Framework 是.NET Framework的精裝版,封裝了一部分.NET Framework的功能,但是不完全包含.NET Framework的所有功能。Native Code具有完全通路系統API和服務,平台API的能力,而.NET Framework不完全具備,.NET Compact Framework 就更加不具備,是以從系統可操控性來說,Native Code和Managed Code存在一個gap,這個gap是指有些功能Native Code可以做,但是Managed Code卻無法實作的功能,例如WIFI,Bluetooth。要在.NET Compact Framework 實作這些功能必須通過P/Invoke來實作,關于P/Invoke可以參考一下
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/01/09/1371836.html">.NET Compact Framework 下Win32 API P/Invoke 的使用</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/08/27/1554854.html">開發P/Invoke的工具與Website</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/09/25/Windows_Mobile_CPP_DLL.html">如何在Windows Mobile下使用Native C++動态加載DLL</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/11/09/Windows_Mobile_Native_DLL.html">Windows Mobile和Wince(Windows Embedded CE)下如何封裝Native DLL提供給.NET Compact Framework進行調用</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/11/18/Windows-Mobile-Native-DLL.html">Windows Mobile和Wince(Windows Embedded CE)下封裝Native DLL進一步探讨</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/12/07/Windows-Mobile-Native-DLL-Callback.html">在Windows Mobile和Wince(Windows Embedded CE)下封裝Native DLL的回調函數</a>
<a target="_blank" href="http://www.cnblogs.com/procoder/archive/2009/12/07/Windows-Mobile-Native-DLL-Callback.html"></a>
Balabala...說那麼多還是沒有說到底如何選擇,其實是trade-off(均衡),沒有絕對真理,還是根據具體需求,結合上述Native Code和Managed Code的特點來選擇。我自己的經驗,如果速度要求快,記憶體要求少的核心子產品都是使用Native C++(一般包括無界面,純資料處理的程式和完全自定義界面的GDI程式),其他子產品都用.NET Compact Framework。如果一個子產品需要大量使用P/Invoke,也是需要考慮使用Native C++來代替.NET Compact Framework的。目前覺得選擇還是OK的。
寫到這裡,希望看官能明白,有疑問請回複交流。下午Christmas party, happy去。
本文轉自Jake Lin部落格園部落格,原文連結:http://www.cnblogs.com/procoder/archive/2009/12/16/Windows-Mobile-Native-CPP-VS-CompactFramework.html,如需轉載請自行聯系原作者