Mono 把 .NET 应用程序移植到 Linux
Mono 是基于 .NET 的开放源码开发平台,它让您可以使用各种 .NET 兼容语言创建强大、灵活的 Linux® 应用程序,同时利用跨平台的能力。本文带领您在系统上安装 Mono,并开发第一个用 Mono 编译的可同时在 Linux 和 ® Windows® 上运行的 C# 应用程序。
C# 语言是一种面向对象的语言,用于为 Microsoft .NET 平台快速构建各种应用程序。C# 和 .NET 的目标是把您从底层的编程问题中解脱出来,如类型安全问题、内存管理、库构造等,以便把精力集中到构建应用程序和业务逻辑上。从而可以帮助缩短开发周期。
随着 C# 和 .NET 战略喧嚣尘上,有人可能在想 Linux 社区将作出什么样的反应。本文讨论开放源码世界(在 Novell 的强力支持下)如何通过实现自己的编译器和类库来欢迎这种语言。(实际上,有多种开放源码实现在进行中。)
本文讨论 Mono,这是 Novell 发起的基于 .NET 框架的开放源码开发平台。本文引导您在系统上安装 Mono,并开发第一个用 Mono 编译的、可在 Microsoft Windows 和 linux 上运行的 C# 示例应用程序。
Mono 赋予了开放源码程序员使用各种 .NET 兼容语言为 Linux 构建应用程序同时保持跨平台性的强大编程能力和灵活性。对于当前的 .NET 开发人员来说,Mono 的主要优点是提供了到 Linux 的更容易的迁移路径。 Mono 项目拥有非常开放和活跃的开发社区,为开发人员提供了运行 .NET 客户机和服务器应用程序的工具和基础设施。
使用 Mono 体系结构最大的好处可能是获得了语言无关。Mono 可以让您利用用 .NET 运行环境所支持的语言编写的任何已有代码
考虑下面这种情况,即传统的 Linux 编程通常完全用 C 来完成。如果希望使用其他语言,比如 Pyhthon,通常需要对原生 C 代码使用 Python 绑定。
创建绑定这种方法不一定是最优或者最容易的,而且有时候不存在绑定,因此,从任何支持 Mono 的语言,Mono 都允许您访问任何另一支持 Mono 的语言的已有代码。可以使用 C#、Python 甚至 Java™ 编写应用程序同时重用其他语言编写的类,而不需要绑定!(从 C# 程序通过 Platform Invocation Facility [pinvoke] 使用 C 库代码就是一个例子,稍后还将提到。)
如前所述,您的代码获得了平台独立性。这是自动进行的,因为 .NET 代码并没有编译成机器码,而是编译成中间语言(IL)。IL 在 Mono 提供的 .NET 运行时中使用,因此可以跨平台复制二进制代码。Java 开发人员非常熟悉这种思想,体现了“一次编写,到处运行”的观念。
Mono 还提供了省时、免费的 .NET 框架类库实现。这些针对各种常见设计任务(包括不那么常见的任务)而设计的库已经写好并经过测试。库包括最常用的数据结构、加密库、XML 和 Web 服务支持。
虽然 .NET 框架中可使用很多种语言,但是 C# 最为 .NET 开发人员所看重。C# 是一种高效、带有无用单元回收的语言,提供了强大的面向对象能力,可以让您迅速进入编程任务的核心。这种语言的语法对于曾经使用现代基于 C 的语言编程的任何人都非常熟悉,但是又包括使用现代脚本语言的那些人所熟悉的便利特性。
最后,Mono JIT (Just In Time) 编译器速度很快,在适当的性能水准的基础上提供了所有这些好处。
Mono 项目包括以下开放源码实现:
- C# 编译器
- 虚拟执行系统(Virtual Execution System),包括 JIT 编译器、无用单元回收程序、装载器和线程引擎
- .NET 类库实现
- 可视化开发工具和调试器
Mono 项目工具可运行在不同硬件和操作系统上,包括 Linux、Windows 和 Mac OS X。
Mono 项目目前在不同程度上支持下列语言:
- C#
- Java
- Boo
- Nemerle
- Visual Basic.NET
- Python
- JavaScript
- Oberon
- PHP
- Object Pascal
- 等等
注意,并非每一种都像 C# 运行时那样完整。比如,没有直接支持 Java,而是将 Java 字节码即时转换成 IL。
实现程度不同的另一个例子是,Python 实现最近似乎停止了。需要 Python 的开发人员可能想使用 Boo,这是一种更完整的脚本语言实现(虽然类似于 Python,但是是为 .NET 框架设计的)。谈到支持 Mono 的语言,需要提一下 Nemerle 是一种新的 .NET 平台混合编程语言(函数型、面向对象型和命令型)。
有人可能奇怪,开放源码的倡导者为何要接受 Microsoft 产品并欢迎它。事实上,很多人最初都好奇 Microsoft 为何允许这种事情。
原因最终被证明是,Microsoft 一直遵守关于标准化 C# 和 CLI 的承诺。由于标准化和规范化,所以 Mono 团队能够为 C# 和公共语言基础设施建立自己的 ECMA 标准的开放实现。事实上,编译器和语言本身也都明确规定让他人实现。
关于 Mono 的大量纷争更多来自关于提供类库对于开放式规范是否必需的讨论。最终必然导致了关于专利权的激烈争论,以及作为攻击 Linux 的更大战略的一部分 Microsoft 是否会利用专利权攻击 Mono。最终,Mono 开发人员提供了两套独立的库。
一套是 Microsoft .NET 库的重新实现,用于和 Microsoft .NET 应用程序兼容。其中包括 ADO.NET、System.Windows.Forms 和 ASP.NET。
以已有的开放源码库和技术为基础,Mono 开发人员还从头创建了自己的一套强大的库,目的是提供同样的功能而避免专利侵权问题。比如,Mono 提供了称为 Gtk# 的窗口技术、用于 gtk+ 的一套 C# 绑定和种类齐全的 GNOME 库。这就使得应用程序开发人员能够使用 Mono 编写完全原生的 GNOME 应用程序。可以将其看作 Microsoft System.Windows.Forms 库的开发源码对照版。
Mono 已经成功移植到多种硬件平台上的 Linux、FreeBSD、Windows 和 Mac OS X。估计涵盖了桌面市场的 99%。
平台 |
解释器 |
即时编译器(更快) |
---|---|---|
Linux/Alpha |
是 |
无 |
Linux/ARM |
是 |
是 |
Linux/MIPS |
是 |
无 |
Linux (PPC) |
是 |
是 |
Linux (S390) |
是 |
是 |
Linux/SPARC |
是 |
是 |
Linux (x86) |
是 |
是 |
Linux/x86-64(64 位端口) |
是 |
是 |
FreeBSD (x86) |
是 |
是 |
HP-UX/HPPA |
是 |
无 |
MacOS X |
是 |
是 |
Solaris/SPARC v8 |
是 |
是 |
Solaris/SPARC v9 (64-bit port) |
是 |
是 |
Windows 2000/XP |
是 |
是 |
现在来看看安装 Mono 过程中的一些差别。
在 Windows 操作系统上安装 Mono,需要运行 Windows 2000 或 Windows XP。首先从 NovellForge 上 Mono Windows Integeration Project 主页下载最新版本的 Mono Win32 安装程序(请参阅本文最后的 参考资料)。下载完成后运行可执行的安装程序。
安装过程和其他产品的安装类似。首先提示您接受还是拒绝许可协议。接受之后,只需要提供安装路径和选择可选的组件。
为了学习 Mono 框架,建议使用默认安装,它为常用工具提供了启动菜单项。这些工具都被放到新的“Mono-1.1.7 for Windows”程序组中。
多数情况下安装 Mono for Linux 相对容易一些(获得每种发行版的要求不在本文讨论之列)。
为 SUSE、Red Hat 和 Ubuntu 以及其他很多版本准备了现成的二进制安装包。基于源代码的发行版如 Gentoo 也很容易获得,只需要很少的工作就能运行。
为了测试核心编译器(mcs)和运行时(mono),应该创建一个简单的程序并编译它。可以在喜欢的任何文本编辑器中创建程序。这里采用一种快速而简陋的方法创建该文件(虽然没有任何格式化),从终端提示符中运行下列命令(都在一行中):
$ echo 'class X { static void Main () { System.Console.Write("My first
mono app worked!n");} }' > example.cs
。
该命令创建一个名为 example.cs 的 C# 源文件(也可从下面的 下载 部分下载该文件 example.cs 和可执行文件 example.exe。(注意,如果使用 Linux 可直接使用 bash 提示符,如果使用 Windows 则需要从开始菜单中调用 Mono 命令提示符。)
要测试编译器创建可执行文件的能力,可输入下面的命令:
$ mcs example.cs
这样将生成名为 example.exe 的二进制文件。要运行它来测试运行时,可使用该命令:
$ mono example.exe
如果一切正常,就会在控制台中看到“My first mono app worked!”字样。
事实上,可以将得到的可执行文件复制到其他系统上,比如运行 Windows 的系统上,无需修改就可以执行。
使用 Mono 平台更有说服力的原因是能够使用已有的、可能不属于 C# 库的 C# 代码。下面是这样的一个例子(也可以从下面的 下载 部分下载清单 2 PInvokeExample.cs 和可执行文件 PInvokeExample.exe)。
提供这种能力的机制是 Platform Invocation Facility(缩写为 pinvoke)。
清单 2. 使用 Platform Invocation Facility
/* Platform Invocation Facility Example This code is intended to illustrate P/Invoke. For out purposes we will access a c shared library. */ using System; // This is a lot of the magic! using System.Runtime.InteropServices; /* Class illustrates pinvoking existing c library code */ public class PInvokeExample { /* Notifying the runtime that we need an additional mathematics library, libm.so */ [DllImport("libm")] /* Here we define the external function we will be using from the library, You must declare these methods to be static. The function signature you provide must match the signature in the external library! */ static extern double sqrt ( double element ); public static void Main () { Console.WriteLine("The square root of 100.0 is {0}.", sqrt(100.0)); } } |
---|
从上述简化的代码中可以看出,只需要告诉 Mono 编译器使用什么库(在 DLLImport
一行中完成)并提供要使用的函数的原型。如果在 Linux 系统上编译这个类,控制台将显示正确的结果。
Mono 的运行时还可以嵌入到应用程序中,从而简化打包和发送。此外,Mono 项目还提供集成开发环境、调试器和文档浏览器。
如果希望进一步了解 C# 和 .NET 框架,下面列出了各种 参考资料,包括各种用于简化开发过程的集成开发环境如 Eclipse 和 Monodevelop 的参考资料。 如果对使用 Mono 开发图形化的应用程序感兴趣,强烈推荐“Mono: A Developers Notebook”,这是一篇更深入的教程(参考资料)。 Novell 程序员仍然在为 Mono 增加新的功能,提供减轻开放源码开发人员工作负担的工具。我希望本文能够帮助您对 Mono 项目有足够的认识,以便在下一个 Linux 开发项目中使用它。
描述 |
名字 |
大小 |
下载方法 |
---|---|---|---|
Installation test source |
example.cs |
1 KB |
FTP |
Installation test executable |
example.exe |
3 KB |
FTP |
PInvoke sample source |
PInvokeExample.cs |
1 KB |
FTP |
PInvoke sample executable |
PInvokeExample.exe |
3 KB |
FTP |
学习
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文。
- 进一步了解 Standard ECMA-334, the C# Language Specification。
- Got Mono 是 Mono 社区的主页。
- Mono Documentation Library 包括关于 Mono 类库的文档。
- 如果希望快速掌握 Java 语言,请阅读“走上开放之路: .NET 开发人员的 J2EE 基础”(2004 年 2 月),这是帮助 .NET 开发人员完成转换的系列文章的第 1 部分。
- “安全设置运行 Java 服务的 Linux”(developerWorks,2003 年 4 月)包括 C# 和 Mono 项目的介绍。
- “实现用于 DB2 UDB 的 .NET 托管提供程序”(developerWorks,2003 年 5 月)提供了更多关于 .NET 技术和 Mono 的信息。
- “Monodoc Tutorial”提供了 Mono 文档开发指南。
- “C#, the natural progression”(developerWorks,2000 年 8 月)说明了 C# 在语言系统中的地位。
- Mono: A Developer's Notebook(O'Reilly,2004 年 7 月)是一本没有废话的、实验室风格的 Mono 1.0 指南,包括 50 个小项目。
- Mono Kick Start(Sams,2003 年 9 月)是关于 Mono 和用 Mono 进行 .NET 兼容应用程序编程的实用入门。
- Mono Project 语言页面提供了 Mono 兼容语言 的详细说明。
- 在 developerWorks Linux 专区 可以找到更多 Linux 资源。
获得产品和技术
- 从 Mono Project 下载页面 下载不同平台的 Mono 版本。
- Eclipse for developing Mono applications 提供了将 Eclipse IDE 用于 C# 和其他 Mono 语言的信息。
- DotGNU 为 Web 服务和 C# 程序提供了免费的软件解决方案。
- MonoDevelop 项目将 SharpDevelop 移植到 Gtk# 以便为 C# 和 Mono 建立最完善的 UNIX 系统开发环境。
- Gtk# 包含用于 gtk+ 工具箱和种类齐全的 GNOME 库的一组 C# 绑定。
- Mono Windows Integration Project 开发在 Windows 上使用的 Mono 及其工具集。
- 订购免费的 SEK for Linux,这套 DVD(两张),包括来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的最新 IBM Linux 试用软件。
- 使用 IBM 试用软件 构建您的下一个开发项目,该软件可直接从 developerWorks 下载。
讨论
- 要联系 Mono 社区,请访问 Mono 社区论坛。
- 通过参与 developerWorks blog 加入 developerWorks 社区。
Eli Dow 是纽约 Poughkeepsie IBM Linux Test and Integration Center 的一位软件工程师。他从 clarkson 大学获得了计算机科学、心理学硕士学位和计算机科学博士学位。他的兴趣范围包括 GNOME 桌面、人机交互和 Linux 系统编程。可以通过emdow@us.ibm.com与 Eli 联系。
http://www-128.ibm.com/developerworks/cn/linux/l-mono/index.html
- 最全爬虫攻略:微博、APP、公众号一个不能少!
- 注册中心 Eureka 源码解析 —— Eureka-Client 初始化(一)之 EurekaInstanceConfig
- 无论人工智能发展到什么地步,都离不开这6段代码
- Dubbo源码解析 —— 逻辑层设计之服务降级
- 【死磕Java并发】-----J.U.C之Condition
- 数据库中间件 MyCAT 源码分析 —— 【单库单表】查询
- 数据库中间件 MyCAT源码分析:【单库单表】插入
- 数据库中间件 MyCAT 源码分析 —— 调试环境搭建
- 分布式事务 TCC-Transaction 源码解析 —— 事务存储器
- 注册中心 Eureka 源码解析 —— 调试环境搭建
- 一样的代码、不一样的写法,JavaScript必知的简写技巧|附源代码
- 【死磕Java并发】-----J.U.C之读写锁:ReentrantReadWriteLock
- 数据库中间件 MyCAT源码分析——跨库两表Join
- iOS一种动态栅格布局方案
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- IE浏览器主页被劫持,如何解决主页被篡改问题?
- 参与国际化项目一定要遵循的java命名规范
- 威胁事件告警分析技巧及处置(二)
- 组复制安全 | 全方位认识 MySQL 8.0 Group Replication
- 那些年我们遇的bug
- Spring 里那么多种 CORS 的配置方式,到底有什么区别
- oracle 数据库:"ORA-01940: 无法删除当前连接的用户",解决办法
- 不要在Spring单元测试中使用 @Transactional注解
- OpenCV DNN模块官方教程(一)加载Caffe模型做图像分类
- Python爬虫之mongodb的聚合操作
- Linux中文输入法-搜狗输入法安装方法
- oracle 数据库问题:"ORA-01922: 必须指定 CASCADE 以删除...",原因及解决办法
- OpenCV DNN模块官方教程(二)YoloV4目标检测实例
- Python爬虫之mongodb的增删改查
- 恕我直言你可能真的不会java第2篇:Java Stream API?