zoukankan      html  css  js  c++  java
  • Write Once, Run Anywhere:这不是Java,这是C#

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

    UPDATED: 25th August 2012

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

    © Conmajia 2012

    引言

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

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

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

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

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

    Mono的大名,搞.NET的朋友相信都知道。它使.NET程序在Linux下有了跨平台运行的可能。Mono目前支持到.NET v4.0,已经逐渐趋于稳定和流行了(参见《兼容性》一节)。由于我只会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

    这里说个题外话。尽管对于已经广泛使用的技术(如.NET)而言,运行时的文件大小已经没有太大的讨论意义,但是仍然有人拿这个说事,以此说明.NET Framework是如何如何不好(其实Win Vista之后这已经不算事了)。那么Mono的表现又如何呢?
    Mono的完全安装大小为78MB(Java最小安装尺寸95MB),而Mono最小化安装之需要7MB。(参考文献:http://www.infoq.com/cn/news/2007/07/Mono-Runtime-Size

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

    安装命令如下:

    $ sudo apt-get install monodevelop

    Linux下编译

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

    命令行程序

    复制代码
     1 using System;
     2  
     3 namespace Test
     4 {
     5     class Program
     6     {
     7         static void Main()
     8         {
     9             Console.WriteLine("Hello Mono!");
    10             Console.ReadLine();
    11         }
    12     }
    13 }
    复制代码

    运行结果

    WinForm程序

    复制代码
     1 using System;
     2 using System.Windows.Forms;
     3 
     4 namespace test
     5 {
     6     public class MainForm:Form
     7     {        
     8         TextBox textBox1;
     9         Button button1;
    10         public MainForm ()
    11         {
    12             textBox1=new TextBox();
    13             textBox1.Text="Text here...";
    14             textBox1.Location=new System.Drawing.Point(10,10);
    15             button1=new Button();
    16             button1.Text="Click me.";
    17             button1.AutoSize=true;
    18             button1.Location=new System.Drawing.Point(10,40);
    19             this.Controls.Add (textBox1);
    20             this.Controls.Add (button1);
    21         }        
    22     }
    23 }
    复制代码

    运行结果

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

    Compile Once, Run Anywhere:跨平台的终极目标

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

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

    然后是在Linux下运行。

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

    运行效果如下

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

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

    Windows下是这样的

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

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

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

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

    复制代码
    1 [DllImport("Shell32.dll")]
    2 static extern int SHGetFileInfo(
    3   string pszPath,
    4   uint dwFileAttributes,
    5   ref   SHFILEINFO psfi,
    6   uint cbFileInfo,
    7   uint uFlags
    8 );
    复制代码

    在Windows中工作正常

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

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

    兼容性

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

    官方给出的兼容性可以在这个页面察看:http://www.mono-project.com/Compatibility

    目前最新的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”(笑)。

  • 相关阅读:
    Java如何编写自动售票机程序
    install windows service
    redis SERVER INSTALL WINDOWS SERVICE
    上传文件
    This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.
    解决Uploadify上传控件加载导致的GET 404 Not Found问题
    OracleServiceORCL服务不见了怎么办
    Access to the temp directory is denied. Identity 'NT AUTHORITYNETWORK SERVICE' under which XmlSerializer is running does not have sufficient permiss
    MSSQL Server 2008 数据库安装失败
    数据库数据导出成XML文件
  • 原文地址:https://www.cnblogs.com/zhangyubao/p/7016894.html
Copyright © 2011-2022 走看看