張浩
摘要:C#作為一種被廣泛使用的開發(fā)語言除了運行在windows平臺之外,越來越多的需求希望其可以支持跨平臺的開發(fā)和部署,而這其中有很多的技術(shù)概念、方案思路需要梳理,以及很多因素和細(xì)節(jié)需要澄清和驗證。該文將會探討C#語言目前所支持的跨平臺可行性技術(shù)方案,在目前主流的Windows和Linux版本下進行了具體的實踐驗證,并展望未來的發(fā)展方向。
關(guān)鍵詞:C#語言;跨平臺;Linux
中圖分類號:G642 ? ? ? ?文獻(xiàn)標(biāo)識碼: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 概述
在企業(yè)實際的應(yīng)用項目開發(fā)中,由于應(yīng)用場景的需要或是客戶的直接需求,希望所開發(fā)的應(yīng)用程序,能夠跨平臺運行。對于開發(fā)團隊來講,希望通過對某種語言的一次性編寫及對一套代碼的一次編譯,就可以實現(xiàn)應(yīng)用程序的跨平臺運行。例如,所開發(fā)出的應(yīng)用程序既可以在Windows下運行又可以在Linux下運行,這樣可以提高程序的開發(fā)效率而無需進行基于某個特定平臺的開發(fā),無需維護多套代碼,從而提高了應(yīng)用程序的可移植性。
C#語言是一種很受歡迎的主流編程語言,其綜合了C++和JAVA的很多優(yōu)點,具有編譯快,執(zhí)行效率高等特點,再加上微軟提供的強大的可視化Visual Studio集成開發(fā)環(huán)境和所支持的類庫,使得C#的開發(fā)效率較高,從而到了廣泛的應(yīng)用,是應(yīng)用軟件開發(fā)的主流趨勢之一。
然而,由于歷史原因C#語言及其經(jīng)典的.net framework類庫,實際上是綁定了windows的開發(fā)及運行平臺。無法移植到Linux上使用,這制約了項目開發(fā)部署的靈活性和可移植性。而利用C#語言的優(yōu)秀特性和其強大的類庫,實現(xiàn)跨平臺的開發(fā)運行又是一個不錯的構(gòu)想。也就是實現(xiàn)代碼編寫后的“一次編譯到處運行”的構(gòu)想。對于目前的基于C#技術(shù)的軟件系統(tǒng)來講,結(jié)合需求,如果可以做到一次開發(fā)至少可以在Windows和Linux兩種平臺下運行的構(gòu)想也是很不錯的。以上構(gòu)想如果可以實現(xiàn),對于編程語言的統(tǒng)一開發(fā)、構(gòu)建、部署及運行調(diào)試都有重要的意義??梢蕴岣哕浖拈_發(fā)效率和降低維護的成本,對增加代碼編寫的可移植性和模塊部署的靈活性都有很大意義,在一定程度上有利于提高行業(yè)應(yīng)用軟件自主化的程度,降低運營成本。
2 C#跨平臺相關(guān)技術(shù)路線
目前支持C#語言開發(fā)環(huán)境及類庫的情況總覽如下圖:
2.1 C#語言及環(huán)境
一種語言要想在某個平臺上編譯和運行,必須具有在該平臺之上所支持的開發(fā)編譯環(huán)境和運行環(huán)境。也就是說,一個應(yīng)用程序?qū)嶋H上是使用一種語言(例如C#)基于一個平臺(Window),利用某個類庫框架(.net framework)運行在某個運行環(huán)境之上(CLR運行時庫)的應(yīng)用程序。
一個.NET應(yīng)用是一個使用.NET Framework類庫來編寫和編譯,并運行于公共語言運行時 Common Language Runtime之上的應(yīng)用程序。
2.2 C#語言遵循規(guī)范——通用語言基礎(chǔ)結(jié)構(gòu)(Common Language Infrastructure,CLI)
C#遵循CLI語言規(guī)范,理論上,只要遵循如上規(guī)范,就應(yīng)該具有平臺的無關(guān)性。CLR實際上是提供了一項使用了虛擬機技術(shù)的產(chǎn)品,他構(gòu)架在操作系統(tǒng)之上,并不要求程序的運行平臺是 Windows系統(tǒng),只要是能夠支持它的運行庫的系統(tǒng),都可以在上面運行.NET應(yīng)用。所以,一個完全由托管代碼組成的應(yīng)用程序,只要編譯一次,就可以在任何支持.NET的平臺上運行。
但現(xiàn)狀是.net framework 的CLR是微軟公司對CLI的實現(xiàn),由于微軟的戰(zhàn)略上及歷史原因,實際上到目前為止,.net framework仍然是Windows平臺的實現(xiàn)版本,未能夠?qū)崿F(xiàn)跨平臺的框架,或者說.net framework是Windows平臺的專有實現(xiàn),發(fā)揮了Windows平臺的最大優(yōu)勢及平臺相關(guān)的特性,并不是為跨平臺準(zhǔn)備的解決方案。
2.3 跨平臺社區(qū)的興起及Mono的出現(xiàn)
在Mono的官網(wǎng)上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是一個旨在提供給開發(fā)者易于創(chuàng)建跨平臺應(yīng)用程序的軟件平臺,是.Net 基金會的組成部分。
我的理解是Mono是一個軟件平臺,是開源的、跨平臺的.Net 框架實現(xiàn)版本。我們應(yīng)用軟件項目所關(guān)心的,實際上是基于Linux的C#.net framework桌面程序的實現(xiàn)版本,本文也是以此為研究方向。
2.4 Mono與Microsoft的合流
Xamarin公司是Mono項目的主導(dǎo)者,還包括提供移動端iOS、Android等多種系統(tǒng)的跨平臺實現(xiàn)。Mono項目原來由Xamarin公司主導(dǎo),后來被微軟收購,實現(xiàn)了合流。這使得很多的基于Windows的IDE的開發(fā)者期待VisualStudio提供更強大的跨平臺的集成開發(fā)環(huán)境。目前微軟公司的最新主流產(chǎn)品Visualstudio2017的產(chǎn)品也正是給了人們一些這樣的期待,但目前做得并不好,而且多種特性和各種向?qū)д显谝黄鹨彩亲屓烁杏X有些凌亂。也許微軟公司在接手Mono之后,再加上原來的windows版的.net framework和各種移動端的開發(fā),還沒有完全理順Mono、.net framework和.net Core等框架關(guān)系,或者至少還沒有向人們解釋清楚現(xiàn)狀和未來的發(fā)展方向。
2.5 Mono、.Net Core和.Net Framework
1) 所謂.Net Core: 是微軟新一代的、第一個開源的、具有跨平臺能力的應(yīng)用程序開發(fā)框架,支持在Window,macOS,Linux等系統(tǒng)上的開發(fā)和部署,并且可以在硬件設(shè)備,云服務(wù),和嵌入式/物聯(lián)網(wǎng)方案中進行使用,這是微軟對.Net Core的定位[1]。
可以理解為,.Net Core是基于Windows的傳統(tǒng).Net Framework的升級和重構(gòu),但不是簡單包含和兼容關(guān)系,.Net Core具有很多新的特性,定位也高于傳統(tǒng)的.Net Framework,是微軟公司新的.net 框架的戰(zhàn)略升級。.Net Core基于跨平臺能力,目前并沒有將與 GUI 高度相關(guān)的 API 移植到 .NET Core 內(nèi),因此像是Windows Forms或是Windows Presentation Foundation(WPF) 并未移植到 .NET Core。
目前VS2017集成開發(fā)環(huán)境的.NET Core 僅支持控制臺應(yīng)用程序 (Console Application) 以及類庫 (Class Library) 類型的項目。因此.Net Core不支持桌面的WinForms和WPF的應(yīng)用開發(fā)。
2) Mono:可以理解是Mono.Net Framework的跨平臺實現(xiàn),他是支持.net框架應(yīng)用模型的子集,例如支持基于WinForms的應(yīng)用模型開發(fā),但不支持WPF。支持.NET Framework APIs中的大多數(shù)甚至使用相同的程序集名稱。
3) 他們之間的關(guān)系:Mono要早于并獨立于.Net Core,自成體系,后來被微軟收購,他們共存、各有特點、互相補充。目前來講,.net Core和Mono互補的提供了不同方式應(yīng)用模型的解決方案。也就是說從目前來看,傳統(tǒng)的基于Windows的.Net Framework、Mono和新生的.Net Core成三足鼎立之勢。但從長遠(yuǎn)來講,可以預(yù)見.Net Core是微軟公司的一個重要戰(zhàn)略,基于windows的.Net Framework和跨平臺的.Net Core將共同遵循一套標(biāo)準(zhǔn)和基礎(chǔ)設(shè)施,以提高維護的統(tǒng)一性,面向特定平臺/跨平臺的應(yīng)用。Mono和經(jīng)典的.Net Framework將會因為.Net Core的升級而發(fā)生演變,我們拭目以待。
2.6 Mono跨平臺的支持范圍
Mono目前實現(xiàn)跨平臺的.Net類庫實際上是基于windows的.Net Framework的一個子集:
1) 目前支持:支持控制臺的應(yīng)用模型和WinForms的桌面的應(yīng)用模型,以及其他一些移動端平臺的應(yīng)用。在于.Net Framework 兼容性方面,Mono的官網(wǎng)這樣描述:
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跨平臺
有關(guān)WPF,Mono的官網(wǎng)上特地給予了明確的說明:
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項目組中沒有任何實現(xiàn)WPFAPI的計劃。我們連這方面的計劃都沒有,是因為這個項目太大而且社區(qū)也沒有對于這方面太多的興趣而為此推動他前進。
3 C#語言跨平臺實踐
3.1 方向目標(biāo)
1) 根據(jù)以上的調(diào)研基礎(chǔ),結(jié)合行業(yè)應(yīng)用軟件的特點,我們的主要感興趣的是如何使用C#開發(fā)基于桌面的跨平臺應(yīng)用程序。C#語言對于界面程序,除了WPF之外,目前以WinForms的應(yīng)用場景最為廣泛,目標(biāo)也是想以Windows平臺為開發(fā)和集成調(diào)試環(huán)境,而基于Windows/Linux平臺的部署應(yīng)用。開發(fā)人員的工作環(huán)境一般如下:
2) 開發(fā)環(huán)境:
Windows平臺+VisualStudio2017+.Net Framework +Mono VS Add-in
(Cross compiler/Debug)
3) 運行環(huán)境:
Windows+ .Net CLR或者Linux+Mono.Net CLR
4) 也就是說我們按照VS2017+Mono交叉編譯、調(diào)試插件+Mono編譯/運行環(huán)境+WinForms應(yīng)用模型,同時運行于Win10和CentOS7.5下的測試路線開始Demo程序的編寫和環(huán)境的搭建及調(diào)試。
3.2 ?特定(版本)開發(fā)及運行環(huán)境的搭建
1) Windows以Win10為測試環(huán)境
2) Linux以CentOS7為測試環(huán)境(CentOS Linux release 7.5.1804 (Core))(本示例采用基于VMwareWorkstation的CentOS7.5的Linux虛擬機環(huán)境)。
3) Mono環(huán)境為Mono5.10.1.57版本 結(jié)合VS2017的Mono擴展編譯調(diào)試插件。
4) 開發(fā)環(huán)境VS2017+ MonoTools.vsix1.0.0(Mono交叉編譯、調(diào)試的擴展插件)。
3.3 Mono和VisualStudio的集成
1) 與VS集成的Mono編譯/調(diào)試插件MonoTool1.0.0
在Windows上安裝好Mono環(huán)境包后,可以利用Mono提供的命令行對現(xiàn)有的C#代碼進行編譯和運行。另外,基于Windows的開發(fā)環(huán)境是VS2017,目前可以采用一個對應(yīng)VS的Mono擴展插件,可以在VS集成開發(fā)環(huán)境中進行交叉編譯和調(diào)試運行。
3.4 C#跨平臺Demo搭建過程簡述
1) 在Windows中安裝VS2017,選中所需要的安裝負(fù)荷組件;
2) Mono官網(wǎng)下載并分別安裝基于Windows下和Linux下的Mono運行環(huán)境;
3) 在Windows下安裝VS2017的Mono擴展插件并配置Mono的安裝路徑;
4) 測試運行環(huán)境是否安裝成功
可以分別在Windows和CentOS中使用命令行測試環(huán)境是否安裝成功。
為了測試核心編譯器(mcs)和運行時(mono),可以創(chuàng)建一個簡單的控制臺程序進行編譯/運行測試。下面是Linux測試環(huán)境的舉例:
$ mcs ?Demo.cs ? //編譯命令
$ mono Demo.exe//運行命令
如果運行正??梢援a(chǎn)生類似于“HelloWorld”字樣的輸出,表示環(huán)境安裝成功。
5) 在Win10下利用Vs2017開發(fā)一個基于WinForms的對話框程序,并作如下測試:
① 新建一個Tree View控件并添加一些子節(jié)點,創(chuàng)建幾個button,添加樹形控件雙擊消息響應(yīng)函數(shù),彈出消息提示框,在Win10下編譯運行。
② 用Mono菜單在VS2017中調(diào)用Mono插件進行交叉編譯生成可跨平臺的目標(biāo)文件。
③ 在Window10下觀看運行效果
④ 在CentOS7下直接運行在Windows下已經(jīng)編譯好的目標(biāo)文件,查看運行效果。
在CentOS下運行Windows下經(jīng)過交叉編譯器構(gòu)建的目標(biāo)文件,運行效果。
3.5 實踐結(jié)論
1) Windows和Linux平臺下都要安裝好Mono的編譯運行環(huán)境才可以。
2) 在Windows平臺下,只要開發(fā)和編譯環(huán)境搭建好,可以利用Mono的交叉編譯器對如上的WinForms的Demo進行一次編譯,便可以不經(jīng)過代碼的修改在已經(jīng)安裝了Mono的Linux平臺下運行,也就是說可以利用Mono進行一次編譯,實現(xiàn)兩個平臺的多處運行。
3) 該Demo基于.Net Framework的WinForms模型,可以看到基本的button和Tree view控件事件響應(yīng)函數(shù)都可以跨平臺運行。
4 C#跨平臺技術(shù)的注意事項
在如上的示例中成功地演示了C#語言編寫的WinForms程序的跨平臺運行,但是需要注意的是,基于Mono的C#編寫的可以跨平臺應(yīng)用程序需要符合一定的約束要求。
1) 編寫跨平臺的C#代碼,要特別注意編程規(guī)范,以便易于移植,禁止調(diào)用平臺特性相關(guān)的API函數(shù)和類庫,使得代碼不需要進行修改,而更容易進行輕松的移植。
2) 目前很多軟件為了達(dá)到一定的界面風(fēng)格效果,使用了第三方的界面庫,開發(fā)人員如果需要使用這樣的界面庫,則要確認(rèn)該界面庫,是否是基于Winform的并且可以對源碼進行基于Mono環(huán)境的編譯并測試,如果是基于WPF的界面庫則不能進行移植。
3) C#實現(xiàn)的應(yīng)用程序在一次編譯后可以運行在不同的平臺,需要在不同的平臺進行對等的測試,而不能以一種平臺的測試代替另一種平臺的測試。
5 結(jié)論
以上實踐以桌面程序為例,成功的實現(xiàn)了C#基于Winform的應(yīng)用程序在Windows下的開發(fā)和編譯并可以跨平臺運行于Windows和Linux較新的主流操作系統(tǒng)版本上運行,是一個可行的解決方案。
5.1 ?開發(fā)平臺所使用的工具環(huán)境
如果需要開發(fā)跨平臺的C#,其開發(fā)環(huán)境和平臺建議使用Windows10+VisualStudio2017的集成開發(fā)環(huán)境,另外一種方案是使用Mono Develop(XamarinDevelop),盡管該軟件也有Windows的版本,但其編譯、安裝配置過程比起前者煩瑣很多,使用過程中出現(xiàn)這樣那樣的問題,解決起來也耗時費力,開發(fā)人員應(yīng)該將主要精力用于業(yè)務(wù)需求本身而不是煩瑣的安裝及編譯環(huán)境的搭建和配置,這也是在Windows下進行開發(fā)的優(yōu)勢。
5.2 跨平臺技術(shù)還在整合
現(xiàn)有代碼的可移植性,其實就現(xiàn)有階段來講,目前最成熟可行的跨平臺解決方案就是基于C++ 的QT技術(shù),但C#由于其本身的優(yōu)秀特點,發(fā)展勢頭很猛,微軟也開始重視這一領(lǐng)域。
5.3 C#跨平臺技術(shù)的展望
Mono項目盡管已經(jīng)進行了較大發(fā)展,但對于強大的C#語言和類庫的實現(xiàn)其實也還是新鮮事物,其和微軟整合的時間也不長,今后產(chǎn)生較大變化的可能性很高,到目前為止Mono對于C#.Net框架也僅僅實現(xiàn)了部分子集,微軟收購Mono如何對現(xiàn)有的技術(shù)進行定位和整合,例如,.net Core以后是否可以支持桌面應(yīng)用的跨平臺,如果支持了和Mono的兼容性如何處理,使用Mono實現(xiàn)的代碼是否還需要或能夠簡單的移植到.net Core上面。
根據(jù)以上展望,我們相信微軟與Mono整合以后,C#作為一種優(yōu)秀的語言,其跨平臺的可移植性技術(shù)方案將會更加廣泛和成熟。
參考文獻(xiàn):
[1] Christian Nagel. C#高級編程[M]. 李銘,譯.10版.北京: 清華大學(xué)出版社,2017.
【通聯(lián)編輯:王力】