張浩



摘要:C#作為一種被廣泛使用的開發語言除了運行在windows平臺之外,越來越多的需求希望其可以支持跨平臺的開發和部署,而這其中有很多的技術概念、方案思路需要梳理,以及很多因素和細節需要澄清和驗證。該文將會探討C#語言目前所支持的跨平臺可行性技術方案,在目前主流的Windows和Linux版本下進行了具體的實踐驗證,并展望未來的發展方向。
關鍵詞:C#語言;跨平臺;Linux
中圖分類號:G642 ? ? ? ?文獻標識碼:A
文章編號:1009-3044(2019)13-0109-04
Abstract: C# language is more and more popular programing language that is expected to
support cross-platform development and deployment not only running on Windows but also ?running on Linux platform. There are many technical concepts, solutions and ideas that need to be combed, and many factors and details need to be clarified.This paper will discuss C# language portability and solution of cross-platform, verify in the current main versions of Windows and Linux and look forward to the future Development direction.
Key words: C # language; cross-platform; Linux
1 概述
在企業實際的應用項目開發中,由于應用場景的需要或是客戶的直接需求,希望所開發的應用程序,能夠跨平臺運行。對于開發團隊來講,希望通過對某種語言的一次性編寫及對一套代碼的一次編譯,就可以實現應用程序的跨平臺運行。例如,所開發出的應用程序既可以在Windows下運行又可以在Linux下運行,這樣可以提高程序的開發效率而無需進行基于某個特定平臺的開發,無需維護多套代碼,從而提高了應用程序的可移植性。
C#語言是一種很受歡迎的主流編程語言,其綜合了C++和JAVA的很多優點,具有編譯快,執行效率高等特點,再加上微軟提供的強大的可視化Visual Studio集成開發環境和所支持的類庫,使得C#的開發效率較高,從而到了廣泛的應用,是應用軟件開發的主流趨勢之一。
然而,由于歷史原因C#語言及其經典的.net framework類庫,實際上是綁定了windows的開發及運行平臺。無法移植到Linux上使用,這制約了項目開發部署的靈活性和可移植性。而利用C#語言的優秀特性和其強大的類庫,實現跨平臺的開發運行又是一個不錯的構想。也就是實現代碼編寫后的“一次編譯到處運行”的構想。對于目前的基于C#技術的軟件系統來講,結合需求,如果可以做到一次開發至少可以在Windows和Linux兩種平臺下運行的構想也是很不錯的。以上構想如果可以實現,對于編程語言的統一開發、構建、部署及運行調試都有重要的意義。可以提高軟件的開發效率和降低維護的成本,對增加代碼編寫的可移植性和模塊部署的靈活性都有很大意義,在一定程度上有利于提高行業應用軟件自主化的程度,降低運營成本。
2 C#跨平臺相關技術路線
目前支持C#語言開發環境及類庫的情況總覽如下圖:
2.1 C#語言及環境
一種語言要想在某個平臺上編譯和運行,必須具有在該平臺之上所支持的開發編譯環境和運行環境。也就是說,一個應用程序實際上是使用一種語言(例如C#)基于一個平臺(Window),利用某個類庫框架(.net framework)運行在某個運行環境之上(CLR運行時庫)的應用程序。
一個.NET應用是一個使用.NET Framework類庫來編寫和編譯,并運行于公共語言運行時 Common Language Runtime之上的應用程序。
2.2 C#語言遵循規范——通用語言基礎結構(Common Language Infrastructure,CLI)
C#遵循CLI語言規范,理論上,只要遵循如上規范,就應該具有平臺的無關性。CLR實際上是提供了一項使用了虛擬機技術的產品,他構架在操作系統之上,并不要求程序的運行平臺是 Windows系統,只要是能夠支持它的運行庫的系統,都可以在上面運行.NET應用。所以,一個完全由托管代碼組成的應用程序,只要編譯一次,就可以在任何支持.NET的平臺上運行。
但現狀是.net framework 的CLR是微軟公司對CLI的實現,由于微軟的戰略上及歷史原因,實際上到目前為止,.net framework仍然是Windows平臺的實現版本,未能夠實現跨平臺的框架,或者說.net framework是Windows平臺的專有實現,發揮了Windows平臺的最大優勢及平臺相關的特性,并不是為跨平臺準備的解決方案。
2.3 跨平臺社區的興起及Mono的出現
在Mono的官網上https://www.mono-project.com/是這樣描述定義Mono的:
Mono is a software platform designed to allow developers to easily create cross platform applications part of the .NET Foundation.
Mono被這樣定義:Mono是一個旨在提供給開發者易于創建跨平臺應用程序的軟件平臺,是.Net 基金會的組成部分。
我的理解是Mono是一個軟件平臺,是開源的、跨平臺的.Net 框架實現版本。我們應用軟件項目所關心的,實際上是基于Linux的C#.net framework桌面程序的實現版本,本文也是以此為研究方向。
2.4 Mono與Microsoft的合流
Xamarin公司是Mono項目的主導者,還包括提供移動端iOS、Android等多種系統的跨平臺實現。Mono項目原來由Xamarin公司主導,后來被微軟收購,實現了合流。這使得很多的基于Windows的IDE的開發者期待VisualStudio提供更強大的跨平臺的集成開發環境。目前微軟公司的最新主流產品Visualstudio2017的產品也正是給了人們一些這樣的期待,但目前做得并不好,而且多種特性和各種向導整合在一起也是讓人感覺有些凌亂。也許微軟公司在接手Mono之后,再加上原來的windows版的.net framework和各種移動端的開發,還沒有完全理順Mono、.net framework和.net Core等框架關系,或者至少還沒有向人們解釋清楚現狀和未來的發展方向。
2.5 Mono、.Net Core和.Net Framework
1) 所謂.Net Core: 是微軟新一代的、第一個開源的、具有跨平臺能力的應用程序開發框架,支持在Window,macOS,Linux等系統上的開發和部署,并且可以在硬件設備,云服務,和嵌入式/物聯網方案中進行使用,這是微軟對.Net Core的定位[1]。
可以理解為,.Net Core是基于Windows的傳統.Net Framework的升級和重構,但不是簡單包含和兼容關系,.Net Core具有很多新的特性,定位也高于傳統的.Net Framework,是微軟公司新的.net 框架的戰略升級。.Net Core基于跨平臺能力,目前并沒有將與 GUI 高度相關的 API 移植到 .NET Core 內,因此像是Windows Forms或是Windows Presentation Foundation(WPF) 并未移植到 .NET Core。
目前VS2017集成開發環境的.NET Core 僅支持控制臺應用程序 (Console Application) 以及類庫 (Class Library) 類型的項目。因此.Net Core不支持桌面的WinForms和WPF的應用開發。
2) Mono:可以理解是Mono.Net Framework的跨平臺實現,他是支持.net框架應用模型的子集,例如支持基于WinForms的應用模型開發,但不支持WPF。支持.NET Framework APIs中的大多數甚至使用相同的程序集名稱。
3) 他們之間的關系:Mono要早于并獨立于.Net Core,自成體系,后來被微軟收購,他們共存、各有特點、互相補充。目前來講,.net Core和Mono互補的提供了不同方式應用模型的解決方案。也就是說從目前來看,傳統的基于Windows的.Net Framework、Mono和新生的.Net Core成三足鼎立之勢。但從長遠來講,可以預見.Net Core是微軟公司的一個重要戰略,基于windows的.Net Framework和跨平臺的.Net Core將共同遵循一套標準和基礎設施,以提高維護的統一性,面向特定平臺/跨平臺的應用。Mono和經典的.Net Framework將會因為.Net Core的升級而發生演變,我們拭目以待。
2.6 Mono跨平臺的支持范圍
Mono目前實現跨平臺的.Net類庫實際上是基于windows的.Net Framework的一個子集:
1) 目前支持:支持控制臺的應用模型和WinForms的桌面的應用模型,以及其他一些移動端平臺的應用。在于.Net Framework 兼容性方面,Mono的官網這樣描述:
The easiest way to describe what Mono currently supports is: Everything in .NET 4.7 except WPF, WWF, and with limited WCF and limited ASP.NET async stack.
Mono對于.NET 4.7框架中除了不支持WPF, WWF之外,以及部分有限的支持WCF及ASP.NET 異步棧的特性之外,支持其他所有特性。
2) 不支持:目前Mono不支持WPF跨平臺
有關WPF,Mono的官網上特地給予了明確的說明:
At this point, no group in the Mono project has plans to implement Windows Presentation Foundation APIs as part of the project. We do not have any plans because the project is too large and there has not been any serious interest from the community to make this effort move forward.
這方面,Mono項目組中沒有任何實現WPFAPI的計劃。我們連這方面的計劃都沒有,是因為這個項目太大而且社區也沒有對于這方面太多的興趣而為此推動他前進。
3 C#語言跨平臺實踐
3.1 方向目標
1) 根據以上的調研基礎,結合行業應用軟件的特點,我們的主要感興趣的是如何使用C#開發基于桌面的跨平臺應用程序。C#語言對于界面程序,除了WPF之外,目前以WinForms的應用場景最為廣泛,目標也是想以Windows平臺為開發和集成調試環境,而基于Windows/Linux平臺的部署應用。開發人員的工作環境一般如下:
2) 開發環境:
Windows平臺+VisualStudio2017+.Net Framework +Mono VS Add-in
(Cross compiler/Debug)
3) 運行環境:
Windows+ .Net CLR或者Linux+Mono.Net CLR
4) 也就是說我們按照VS2017+Mono交叉編譯、調試插件+Mono編譯/運行環境+WinForms應用模型,同時運行于Win10和CentOS7.5下的測試路線開始Demo程序的編寫和環境的搭建及調試。
3.2 ?特定(版本)開發及運行環境的搭建
1) Windows以Win10為測試環境
2) Linux以CentOS7為測試環境(CentOS Linux release 7.5.1804 (Core))(本示例采用基于VMwareWorkstation的CentOS7.5的Linux虛擬機環境)。
3) Mono環境為Mono5.10.1.57版本 結合VS2017的Mono擴展編譯調試插件。
4) 開發環境VS2017+ MonoTools.vsix1.0.0(Mono交叉編譯、調試的擴展插件)。
3.3 Mono和VisualStudio的集成
1) 與VS集成的Mono編譯/調試插件MonoTool1.0.0
在Windows上安裝好Mono環境包后,可以利用Mono提供的命令行對現有的C#代碼進行編譯和運行。另外,基于Windows的開發環境是VS2017,目前可以采用一個對應VS的Mono擴展插件,可以在VS集成開發環境中進行交叉編譯和調試運行。
3.4 C#跨平臺Demo搭建過程簡述
1) 在Windows中安裝VS2017,選中所需要的安裝負荷組件;
2) Mono官網下載并分別安裝基于Windows下和Linux下的Mono運行環境;
3) 在Windows下安裝VS2017的Mono擴展插件并配置Mono的安裝路徑;
4) 測試運行環境是否安裝成功
可以分別在Windows和CentOS中使用命令行測試環境是否安裝成功。
為了測試核心編譯器(mcs)和運行時(mono),可以創建一個簡單的控制臺程序進行編譯/運行測試。下面是Linux測試環境的舉例:
$ mcs ?Demo.cs ? //編譯命令
$ mono Demo.exe//運行命令
如果運行正常可以產生類似于“HelloWorld”字樣的輸出,表示環境安裝成功。
5) 在Win10下利用Vs2017開發一個基于WinForms的對話框程序,并作如下測試:
① 新建一個Tree View控件并添加一些子節點,創建幾個button,添加樹形控件雙擊消息響應函數,彈出消息提示框,在Win10下編譯運行。
② 用Mono菜單在VS2017中調用Mono插件進行交叉編譯生成可跨平臺的目標文件。
③ 在Window10下觀看運行效果
④ 在CentOS7下直接運行在Windows下已經編譯好的目標文件,查看運行效果。
在CentOS下運行Windows下經過交叉編譯器構建的目標文件,運行效果。
3.5 實踐結論
1) Windows和Linux平臺下都要安裝好Mono的編譯運行環境才可以。
2) 在Windows平臺下,只要開發和編譯環境搭建好,可以利用Mono的交叉編譯器對如上的WinForms的Demo進行一次編譯,便可以不經過代碼的修改在已經安裝了Mono的Linux平臺下運行,也就是說可以利用Mono進行一次編譯,實現兩個平臺的多處運行。
3) 該Demo基于.Net Framework的WinForms模型,可以看到基本的button和Tree view控件事件響應函數都可以跨平臺運行。
4 C#跨平臺技術的注意事項
在如上的示例中成功地演示了C#語言編寫的WinForms程序的跨平臺運行,但是需要注意的是,基于Mono的C#編寫的可以跨平臺應用程序需要符合一定的約束要求。
1) 編寫跨平臺的C#代碼,要特別注意編程規范,以便易于移植,禁止調用平臺特性相關的API函數和類庫,使得代碼不需要進行修改,而更容易進行輕松的移植。
2) 目前很多軟件為了達到一定的界面風格效果,使用了第三方的界面庫,開發人員如果需要使用這樣的界面庫,則要確認該界面庫,是否是基于Winform的并且可以對源碼進行基于Mono環境的編譯并測試,如果是基于WPF的界面庫則不能進行移植。
3) C#實現的應用程序在一次編譯后可以運行在不同的平臺,需要在不同的平臺進行對等的測試,而不能以一種平臺的測試代替另一種平臺的測試。
5 結論
以上實踐以桌面程序為例,成功的實現了C#基于Winform的應用程序在Windows下的開發和編譯并可以跨平臺運行于Windows和Linux較新的主流操作系統版本上運行,是一個可行的解決方案。
5.1 ?開發平臺所使用的工具環境
如果需要開發跨平臺的C#,其開發環境和平臺建議使用Windows10+VisualStudio2017的集成開發環境,另外一種方案是使用Mono Develop(XamarinDevelop),盡管該軟件也有Windows的版本,但其編譯、安裝配置過程比起前者煩瑣很多,使用過程中出現這樣那樣的問題,解決起來也耗時費力,開發人員應該將主要精力用于業務需求本身而不是煩瑣的安裝及編譯環境的搭建和配置,這也是在Windows下進行開發的優勢。
5.2 跨平臺技術還在整合
現有代碼的可移植性,其實就現有階段來講,目前最成熟可行的跨平臺解決方案就是基于C++ 的QT技術,但C#由于其本身的優秀特點,發展勢頭很猛,微軟也開始重視這一領域。
5.3 C#跨平臺技術的展望
Mono項目盡管已經進行了較大發展,但對于強大的C#語言和類庫的實現其實也還是新鮮事物,其和微軟整合的時間也不長,今后產生較大變化的可能性很高,到目前為止Mono對于C#.Net框架也僅僅實現了部分子集,微軟收購Mono如何對現有的技術進行定位和整合,例如,.net Core以后是否可以支持桌面應用的跨平臺,如果支持了和Mono的兼容性如何處理,使用Mono實現的代碼是否還需要或能夠簡單的移植到.net Core上面。
根據以上展望,我們相信微軟與Mono整合以后,C#作為一種優秀的語言,其跨平臺的可移植性技術方案將會更加廣泛和成熟。
參考文獻:
[1] Christian Nagel. C#高級編程[M]. 李銘,譯.10版.北京: 清華大學出版社,2017.
【通聯編輯:王力】