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