博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Write Once, Run Anywhere:这不是Java,这是C#
阅读量:2454 次
发布时间:2019-05-10

本文共 4117 字,大约阅读时间需要 13 分钟。

© Conmajia 2012

备注

注意,本文目的并非挑起语言之争。虽然有为C#平反之意,但主要还是介绍Mono并进行简单的测试。

更新

UPDATE:29th November 2012

重新排版。

UPDATE:25th August 2012

更新了「Compile Once, Run Anywhere:跨平台的终极目标」一节。

对网友的解答

有的朋友观点很有意思(也许是我没理解到位):只运行区区几个小程序,是不能算作跨平台的。我可能水平不够,对此有些疑惑。能在另一个操作系统运行都还不算跨平台吗?而且还是「Compile once」的,都不用你做多余的事。难道我们「会说外语」就要100%的掌握外语的「每一个单词,每一点语法,每一句俚语」吗?汉语我都不敢保证,别说外语了。真正跨平台的是什么?有朋友介绍说FLEX。啊,我豁然开朗了,原来这样啊,那么——虽然我有些奇怪RIA怎么能和Desktop比——不如我们把HTML抬出来吧,比FLEX还要能跨。再进一步,这些都弱爆了,因为它们能跨的操作系统太有限了,在VxWorks、uCOS、eCos、RTX51这些操作系统上面都没法运行,所以真正跨平台的还是ASCII(128个数字而已),只要是个CPU都能识别。(这只是开个玩笑,这样的「跨平台」毫无意义?)

前言

一次编写,到处运行

“Write once, run anywhere”(一次编写,到处运行,WORA),有时也写成“Write once, run everywhere”(WORE),是Sun Microsystem(于2010年被Oracle收购)为宣传Java语言的跨平台特性而提出的口号。在理想情况下——当然常常是不可能的——将Java语言写成的程序编译为标准的字节码(bytecode),就可以运行在支持Java虚拟机(JVM)的任何设备上。

很多半吊子的Java“专家”常常用这点来挤兑.NET的使用者,说他们“被微软绑架了,只有JVM这种业界标准才能跨平台”。

WORA的现实

真实的情况是什么呢?一方面,真正的Java开发者不断抱怨着“Write once, debug anywhere"(一次编写,到处调试),另一方面,越来越多的人认识到.NET的本质实际是CLI/CTS,也是业界标准,CLR也是虚拟机。所以,总是在“跨平台”的能力上突出Java而贬低.NET,已经是落伍和压根不懂的表现了。

起因

安装Linux后

最近我因为电脑运行速度慢,于是删除了Windows,转而安装Linux Mint(一个基于Ubuntu的Linux发行版)。

但是我又只会用C#(或者说懒得用其他语言)编程,MS的.NET框架没法装到Linux来,怎么办?

Linux的.NET runtime

在Linux环境下,有很出名的.NET运行时——Mono。

Mono的大名,搞.NET的朋友相信都知道。它使.NET程序在Linux下有了跨平台运行的可能。Mono目前支持到.NET v3.5,已经逐渐趋于稳定和流行了。由于我只会C#(惭愧),因此需要在Linux下开发和运行.NET程序,于是安装了Mono。

$ sudo apt-get install mono-gmcs libmono-system-data2.0-cil libmono-system-ldap2.0-cil libmono-system-messaging2.0-cil libmono-system-runtime2.0-cil

为了能够方便开发,我直接安装了MonoDevelop。这是Windows上大名鼎鼎的开源.NET IDE SharpDevelop的Linux版本。

安装命令如下:

$ sudo apt-get install monodevelop

Linux下C#编程实战

命令行程序

下面是几个简单的程序测试。注意,这里的程序代码在Windows下是完全可以运行的。

命令行程序

using System;   namespace Test {     class Program     {         static void Main()         {             Console.WriteLine("Hello Mono!");             Console.ReadLine();         }     } }

运行结果

WinForm程序

试过了命令行,该来试试GUI了。平时我所中意的WinForm,在Linux下会是什么样的表现呢?

WinForm程序

using System; using System.Windows.Forms;  namespace test {     public class MainForm:Form     {                 TextBox textBox1;         Button button1;         public MainForm ()         {             textBox1=new TextBox();             textBox1.Text="Text here...";             textBox1.Location=new System.Drawing.Point(10,10);             button1=new Button();             button1.Text="Click me.";             button1.AutoSize=true;             button1.Location=new System.Drawing.Point(10,40);             this.Controls.Add (textBox1);             this.Controls.Add (button1);         }             } }

运行结果

是不是很意外?Linux下面可以直接运行WinForm的程序。就是这么方便。演示代码是在Linux下编译的,还不能证明“Write once, run anywhere”,那么,就直接运行Windows下编译出来的exe又如何?我们来试试编译型程序跨平台的终极目标:Compile once,run anywhere

终极目标:Compile Once, Run Anywhere

WIndows中的表现

下面是我之前在Windows下用Visual Studio编译的exe不做任何处理(也没法处理)直接运行

首先是《蜂巢大战》,先来看看Windows下运行的效果。

Linux中的表现

然后是在Linux下运行。

注意:因为Linux下默认.exe是和归档管理器关联的,所以需要选择打开方式为“Mono Runtime”。

运行效果如下

经测试各种功能正常。说明GDI+工作正常,ToolStrip等控件也运行正常。

多线程的测试

再来看看我最近发表的另一个程序:《InvokeHelper》。

Windows下是这样的

在Mono环境下运行是这个效果

说明和线程相关的功能工作正常。

Windows API不能工作呢?

再来是和Windows API相关的。其实用脚趾头想这也是不可能的(不光C#,随便什么语言都一样,这种和平台API强相关的,怎么可能“跨平台”呢)。

《获取系统图标》,这个程序使用了SHGetFileInfo这个Windows API:

[DllImport("Shell32.dll")] static extern int SHGetFileInfo(   string pszPath,   uint dwFileAttributes,   ref   SHFILEINFO psfi,   uint cbFileInfo,   uint uFlags );

在Windows中工作正常

在Linux下如何呢?运行下试试:

调用打开文件对话框正常,但是一旦运行到Windows API就自动退出。所以,跨了平台后,和平台(Win)相关的API不能用了,这也是理所当然的。C#和Java都没办法跳掉这样的命运(笑)。

兼容性

这里有一个例子展示了目前MONO的一些兼容性情况:支持范型(2.0+)和var(3.0+)。

官方给出的兼容性可以在这个页面察看:

目前最新的Mono is 2.10.8. (Released December 19th, 2011)已经可以支持.NET 4.0版本。参见下图:

移植

选用不同的平台,迟早要面对移植问题。由于CLI/CTS只规定了语言的基础部分,因此各个运行时的实现有部分差异(参见上一节:兼容性)。所以Mono官方提供了一个叫做Mono Migration Analyzer(MOMA,摩码)的移植辅助工具。这个工具可以直接告诉你将一个现成的基于Windows + Microsoft.Net的程序,移植到Win/Linux/Mac + Mono的可能性。

有时候实现一个小功能,实现方式其实有好多种,但有的实现方式是依赖于Windows API的,有的不是,在不影响性能的前提下,我们要优先选择标准实现而不是特殊实现。这就是用Mono做项目的成功秘诀。

总结

目前比较有名的非Windows平台下.NET虚拟机/运行时暂时只有Mono、Portable.NET等,相信随着时间推移,会有更多的Runtime出现,Mono也会变得更强大。到时,不止是Java,C#还有.NET平台下的各种语言(VB、C++/CLI、F#等)都可以实现“Write once, run anywhere”了。当然,还有随之而来的“Debug anywhere”(笑)。

(完)

© Conmajia 2012

转载地址:http://vxdhb.baihongyu.com/

你可能感兴趣的文章
如何在Mac上为Python设置虚拟环境
查看>>
使用Python在GitHub Pages上运行博客
查看>>
如何使用Python和Apache Spark分析日志数据
查看>>
移动端仿钉钉聊天 git_使用Git作为聊天的后端
查看>>
raspberry pi_PiFlash入门:在Linux上启动Raspberry Pi
查看>>
固态硬盘损坏数据如何挽救_开放数据和工具如何在灾难期间挽救生命
查看>>
raspberry_您最老的Raspberry Pi多大了?
查看>>
vscode构建rust_使用rust-vmm构建未来的虚拟化堆栈
查看>>
joplin_介绍Joplin,这是Evernote的开源替代方案
查看>>
使用Pygame模块使用Python构建游戏框架
查看>>
如何使用PostgreSQL简化Python代码
查看>>
软件博览会上的致辞_本地制造商博览会上有4个著名的开源项目
查看>>
pygame游戏角色旋转_使用Pygame移动游戏角色
查看>>
为什么Python和Pygame是入门程序员的最佳选择
查看>>
上海微钉科技面试题_钉住面试的7个技巧
查看>>
linux有桌面有的没桌面_Linux桌面的政治
查看>>
库蒂尼奥_尼奥基入门
查看>>
强化学习入门论文_强化学习入门
查看>>
kubernetes入门_Kubernetes入门
查看>>
aalto 交互_向芬兰的Aalto Fablab付款
查看>>