前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Mono 把 .NET 应用程序移植到 Linux

Mono 把 .NET 应用程序移植到 Linux

作者头像
张善友
发布于 2018-01-29 07:29:23
发布于 2018-01-29 07:29:23
4.5K02
代码可运行
举报
文章被收录于专栏:张善友的专栏张善友的专栏
运行总次数:2
代码可运行

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 的优点

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 的使用

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 运行在什么平台上?

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

现在来看看安装 Mono 过程中的一些差别。

Windows 平台

在 Windows 操作系统上安装 Mono,需要运行 Windows 2000 或 Windows XP。首先从 NovellForge 上 Mono Windows Integeration Project 主页下载最新版本的 Mono Win32 安装程序(请参阅本文最后的 参考资料)。下载完成后运行可执行的安装程序。

安装过程和其他产品的安装类似。首先提示您接受还是拒绝许可协议。接受之后,只需要提供安装路径和选择可选的组件。

为了学习 Mono 框架,建议使用默认安装,它为常用工具提供了启动菜单项。这些工具都被放到新的“Mono-1.1.7 for Windows”程序组中。

Linux 平台

多数情况下安装 Mono for Linux 相对容易一些(获得每种发行版的要求不在本文讨论之列)。

为 SUSE、Red Hat 和 Ubuntu 以及其他很多版本准备了现成的二进制安装包。基于源代码的发行版如 Gentoo 也很容易获得,只需要很少的工作就能运行。

测试 Mono 安装

为了测试核心编译器(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!”字样。

图 1. 正常运行的结果

事实上,可以将得到的可执行文件复制到其他系统上,比如运行 Windows 的系统上,无需修改就可以执行。

使用非 Mono 库的代码

使用 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 系统上编译这个类,控制台将显示正确的结果。

图 2. 使用非 C# 库

Mono 的其他优点

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

参考资料

学习

获得产品和技术

讨论

关于作者

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2006-02-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
【MFC】MFC基础篇(1)
CFrameWnd: 框架窗口,负责创建应用主窗口,含标题栏,菜单栏,工具栏,状态栏等 。
半生瓜的blog
2023/05/13
1.8K0
【MFC】MFC基础篇(1)
CListCtrl实现tooltip信息提示
EnableToolTips(TRUE); m_tooltip.Create(this); m_tooltip.SetMaxTipWidth(500); m_tooltip.Activate(TRUE);
全栈程序员站长
2022/09/09
1.3K0
CListCtrl
建立变量m_listCtrl: 选中控件ctrl+鼠标左键双击 添加控件风格: DWORD exstyle = m_ListCtrl.GetExtendedStyle(); m_ListCtrl.SetExtendedStyle(exstyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | WS_EX_STATICEDGE ); m_ListCtrl.ModifyStyle(0,LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SORTASCENDING); 插入列: m_ListCtrl.InsertColumn(0,_T(“文件名”),LVCFMT_LEFT,60,0); int nItemIndex =m_ListCtrl.InsertItem(j,sServerTmp);//主项目 m_ListCtrl.SetItemText(nItemIndex,nCol+1,sTmp);//次 cstrItemB = m_ListCtrl.GetItemText(行, 列);//获取
全栈程序员站长
2022/09/09
6880
也谈VC中ModifyStyle&ModifyStyleEx无法改变控件的Style)
大家好,又见面了,我是你们的朋友全栈君。一个View中用到了一个CListCtrl,在OnInitialUpdate函数里面他调用了m_listCtrl.ModifyStyleEx(0, LVS_EX_FULLROWSELECT);但是结果是并没有改变View中这个ListCtrl的效果。
全栈程序员站长
2022/09/09
5700
ClistCtrl用法及总结(由怎样隐藏ListCtrl列表头的排序小三角形这个bug学习到的知识)
1 怎样隐藏ListCtrl列表头的排序小三角形 在创建控件是加入|LVS_NOSORTHEADER风格即可。 一下是用法总结: 本文根据本人在项目中的应用,来谈谈CListCtrl的部分用法及技巧。当初学习时,查了很多资料,零零碎碎的作了些记录,现在主要是来做个总结,方便以后查阅。主要包括以下十三点内容:基本操作、获取选中行的行号、复选框操作、动态设置选中行的字体颜色、设置选中行的背景颜色、禁止拖动表头、让第一列居中显示、设置行高与字体、虚拟列表技术、点击表头时进行归类、向上与向下移动、动态调整大小问题、
用户1198337
2018/01/19
3.1K0
ClistCtrl用法及总结(由怎样隐藏ListCtrl列表头的排序小三角形这个bug学习到的知识)
MFC应用程序——标签控件_IP控件_时间控件_List Control控件_Tree Control控件_命令按钮_列表框_组合框_图片_滚动控件「建议收藏」
【Tab Control 标签控件】 标签控件也比较常见。它可以把多个页面集成到一个窗口中, 每个页面对应一个标签,用户点击某个标签时,它对应的页 面就会显示。 使用标签控件我们可以同时加载多个有关联的页面,用 户只需点击标签即可实现页面切换,方便灵活的进行操作。 每个标签除了可以显示标签文本,还可以显示图标。 标签控件相当于是一个页面的容器,可以容纳多个对话 框,而且一般也只容纳对话框,所以我们不能直接在标签控 件上添加其他控件,必须先将其他控件放到对话框中,再将 对话框添加到标签控件中。最终我们点击标签切换页面时, 切换的不是控件的组合,而是对话框。
全栈程序员站长
2022/09/23
2.7K0
MFC应用程序——标签控件_IP控件_时间控件_List Control控件_Tree Control控件_命令按钮_列表框_组合框_图片_滚动控件「建议收藏」
CListCtrl使用「建议收藏」
列表控件可以看作是功能增强的ListBox,它提供了四种风格,而且可以同时显示一列的多中属性值。 MFC中使用CListCtrl类来封装列表控件的各种操作。 通过调用 BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID )创建一个窗口,
全栈程序员站长
2022/09/09
1.4K0
CListCtrl控件使用方法总结
今天第一次用CListCtrl控件,遇到不少问题,查了许多资料,现将用到的一些东西总结如下: 以下未经说明,listctrl默认view 风格为report 相关类及处理函数 MFC:CListCtrl类 SDK:以 “ListView_”开头的一些宏。如 ListView_InsertColumn ---- 1. CListCtrl 风格       LVS_ICON: 为每个item显示大图标       LVS_SMALLICON: 为每个item显示小图标       LVS_LIST:
_gongluck
2018/03/12
2K0
CListCtrl详细使用方法
以下未经说明,listctrl默认view 风格为report 相关类及处理函数 MFC:CListCtrl类 SDK:以 “ListView_”开头的一些宏。如 ListView_InsertColumn
全栈程序员站长
2022/09/09
1.2K0
【大三操作系统实验】 请求页式管理中的置换算法
(1)FIFO算法总是选择在内存驻留时间最长的一页将其淘汰。FIFO算法认为调入内存的页不再被可能性要比其他页大,因而选择最先调入内存的页换出。
用户7886150
2020/12/29
5620
C++学习——memset函数详解
memset是计算机中C/C++语言初始化函数。作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。
全栈程序员站长
2022/09/23
5.8K0
memset的含义及作用
struct sample_struct { char csName[16]; int iSeq; int iType; };
包子388321
2020/06/17
2K0
滴水逆向初级-C++(三)
1、什么是封装: 将函数定义到结构体内部,就是封装。 2、什么是类: 带有函数的结构体,称为类。 3、什么是成员函数: 结构体里面的函数,称为成员函数。
zhang_derek
2021/04/13
6540
MFC/C++学习系列之简单记录11——树控件的使用
文章推荐:一文带你了解机器学习的四大框架PyTorch、TensorFlow、Keras、Scikit-learn
升级打怪的菜鸟
2024/11/25
2970
【C++】memset 函数详解与应用
在接触C++之前,我对编程的了解仅限于一些基础的概念,例如变量、循环和条件语句。C++的学习从这些最基本的部分开始,帮助我夯实了编程的基础。C++的语法严格,这在一开始可能会让人感到不适应,但也正是因为这种严格性,它迫使我养成了良好的编程习惯。例如,必须明确变量的类型,让我更注重程序的逻辑性和可读性。
CSDN-Z
2025/01/03
1.3K0
【C++】memset 函数详解与应用
【C语言】memset()函数(内存块初始化函数)
我们先来看一下cplusplus.com - The C++ Resources Network网站上memset()函数的基本信息:
修修修也
2024/04/01
1.8K0
【C语言】memset()函数(内存块初始化函数)
谈一谈,c/c++中的memset()函数
memset()是计算机中C/C++语言初始化函数,在头文件#include<string.h>中定义。作用是将某一块内存中的内容全部设置为指定的值,这个函数通常为新申请的内存做初始化工作。其函数原型如下:
狼啸风云
2023/10/23
1.8K0
C语言 数组初始化的三种常用方法({0}, memset, for循环赋值)以及原理「建议收藏」
分别执行上面三种方法,统计下平均时间可以得出: for循环浪费的时间最多,{0} 与memset 耗时差不多。
全栈程序员站长
2022/09/09
10.4K0
C语言 数组初始化的三种常用方法({0}, memset, for循环赋值)以及原理「建议收藏」
C++ STL学习之【list的模拟实现】
STL 中的 list 是一个双向带头循环链表,作为链表的终极形态,各项操作性能都很优秀,尤其是 list 中迭代器的设计更是让人拍案叫绝,如此优秀的容器究竟是如何实现的?本文将带你共同揭晓
北 海
2023/07/01
1770
C++ STL学习之【list的模拟实现】
OpenCV 2.2版本号以上显示图片到 MFC 的 Picture Control 控件中
OpenCV 2.2 以及后面的版本号取消掉了 CvvImage.h 和CvvImage.cpp 两个文件,直接导致了苦逼的程序猿无法调用里面的显示函数来将图片显示到 MFC 的 Picture Control 控件中。为此,网上非常多人表示仅仅要将那两个文件人为的提取出来然后放到project里面就解决这个问题了,也提供了两个文件的下载,可是这麻烦不说。还会导致一些奇奇怪怪的报错(至少本人是这种,非常崩溃!)。所以在了解了一些gdi画图之后结合网上的代码写了例如以下的函数,仅仅需调用就能够将OpenCV的图片显示在上面了(仅仅支持三通道不支持单通道),初步測试效率跟原来两个文件差点儿相同。假设有大神请帮我完好这份代码!
全栈程序员站长
2022/07/10
6010
推荐阅读
相关推荐
【MFC】MFC基础篇(1)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验