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