Conmajia

Stop stealing sheep!

导航

< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

统计

☕️ 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”WORESun Microsystem2010年被Oracle收购为宣传Java语言的跨平台特性而提出的口号在理想情况下——当然常常是不可能的——Java语言写成的程序编译为标准的字节码bytecode就可以运行在支持Java虚拟机JVM的任何设备上

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

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

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

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的完全安装大小为78MBJava最小安装尺寸95MBMono最小化安装之需要7MB参考文献http://www.infoq.com/cn/news/2007/07/Mono-Runtime-Size

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

安装命令如下

$ 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 oncerun anywhere

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

下面是我之前在Windows下用Visual StudioSharpDevelop编译的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+var3.0+

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

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

 

移植

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

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

总结

目前比较有名的非Windows平台下.NET虚拟机/运行时暂时只有MonoPortable.NET感谢@鹤冲天相信随着时间推移会有更多的Runtime出现Mono也会变得更强大到时不止是JavaC#还有.NET平台下的各种语言VBC++/CLIF#等都可以实现“Write once, run anywhere”了当然还有随之而来的“Debug anywhere”

 

© Conmajia 2012

posted on2012-08-22   Conmajia  阅读(6066)  评论(0编辑  收藏  举报

编辑推荐:
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
点击右上角即可分享
微信分享提示