web-dev-qa-db-ja.com

モノはどのように機能しますか

Visual Studioの.NETでC#を使用し、openSUSE LinuxのMonoで少し遊んだことがありますが、それがどのように機能するのかよくわかりません。

.NET上のWindowsでアプリを作成する場合、これはMonoとどのように関連しますか? LinuxでWineなしでWindows.exeファイルを実行することはできないため、Windowsで開発されたアプリを実行することはできません。

クロスプラットフォーム開発を容易にするために、Linux(およびその他)で同等の.NETライブラリを使用することだけが目的ですか?たとえば、私がビジネスでLinuxの顧客にリーチしたいが、本当に.NETを使用したい場合は、Monoを選択する必要がありますか?それとも私が見逃しているものが他にありますか?

46
DavidG

Windows EXEには、複数の「パーツ」が含まれています。 簡略化、. netコード(= MSIL)はEXEの一部にすぎず、EXE内には「実際の」ネイティブWindowsパーツもあります。これは、MSILを実行する.netFrameworkのある種のランチャーとして機能します。

MonoはMSILを取得して実行し、ネイティブのWindowsLauncherのものを無視します。

繰り返しますが、これは簡略化された概要です。

編集:私は深い深い詳細の理解が本当に多くの詳細に対して十分ではないことを恐れています(私はPEヘッダーが何であるかを大まかに知っていますが、実際にはそうではありません詳細)、しかし私はこれらのリンクが役に立ちました:

NETアセンブリ構造–パートII

。NET Foundations-.NETアセンブリ構造

22
Michael Stum

これは古い質問です(回答はすでに選択されています)が、質問が実際にうまく回答されているとは思いません。

まず、少し背景...

。NETはどのように機能しますか?

従来のWindows.EXEファイルは、コンピューターが理解し、アプリケーションが利用できるサービスを提供するWindowsの一部であるWin32APIを呼び出す一連の機械語命令を表すバイナリファイルです。使用される機械語はコンピュータの種類に非常に固有であり、Win32呼び出しにより、実行可能ファイルはWindowsに大きく依存します。 .NET実行可能ファイルはそのようなものではありません。

.NET実行可能ファイル(.EXEファイル)は実際にはネイティブのWindowsアプリケーションではないことを理解することが重要です。 Windows自体は、.NET実行可能ファイルでコードを実行する方法を理解していません。あなたのコンピュータもそれを理解していません。

Javaと同様に、.NETアプリケーションは、CIL(Common Intermediate Language)と呼ばれる言語の命令で構成されています。これは、実際には存在しない理想的なコンピューターの機械語と考えることができます。 .NETでは、この理想化されたマシンのソフトウェア実装は、共通言語ランタイム(CLR)と呼ばれます。 Javaの世界で同等のものはJava仮想マシン(JVM)と呼ばれます。Javaでは、CILと同等のものはJavaバイトコード。CILはMSIL(Microsoft Intermediate Language)と呼ばれることもあります。

CILはCLR(理想的なマシン)で実行するように設計されていますが、それ以外はプラットフォームに依存しません。つまり、CILは、使用しているコンピューターの種類や実行しているオペレーティングシステムを気にしません。

Javaを実行する各プラットフォームでJava JVMのネイティブバージョンが必要なのと同じように、.NETCIL実行可能ファイルを実行するにはCLRのネイティブバージョンが必要です。CLRは上記の従来のWin32EXEファイルとまったく同じネイティブWindowsアプリケーション。CLR自体は、実行するように設計されたWindows実装とコンピューターアーキテクチャに固有です。

どの.NET言語(C#、VisualBasic、F#、IronPython、IronRuby、Booなど)で開始するかは関係ありません。これらはすべてCILバイトコードにコンパイルされます。 CILプログラムは、人間が簡単に読めるオブジェクト指向のアセンブリ言語の形式に簡単に「逆アセンブル」できます。 CILで直接自分でプログラムを書くことはできますが、そうする人はほとんどいません。

Windowsでは、CLRは、実行可能ファイルを実行する直前、つまりコードが実際に実行される直前に、このCILコードをジャストインタイム(JIT)でコンパイルします。これは、CILバイトコードがコンピューター上でネイティブに実行される実際のマシンコードに変換(コンパイル)されることを意味します。 CLRのこの部分は、JITコンパイラまたは単にJITと呼ばれます。

現在までに、MicrosoftはCLRの4つのバージョン(1.0、1.1、2.0、および4.0)をリリースしています。そのランタイムを対象とする.NET実行可能ファイルを実行する場合は、適切なバージョンのCLRをマシンにインストールする必要があります。 CLR 2.0は、.NET 2.0、3.0、および3.5アプリケーションをサポートします。 .NETの他のバージョンの場合、.NETバージョンはCLRバージョンにきれいにマップされます。

JIT/CLRに加えて、.NETは、.NET Frameworkの残りの部分を構成し、.NETアプリケーションが呼び出すことができる機能とサービスのホストを提供するライブラリ(アセンブリ)のホストを提供します。これらのアセンブリの大部分は、CLRで実行される純粋なCILコードです。 Windowsでは、Win32APIを呼び出すものもあります。 .NETをインストールすると、CLR、クラスライブラリ(フレームワーク)、および一連の開発ツールがインストールされます。 CLRの各バージョンには、通常、これらの「フレームワーク」アセンブリの完全なセットが必要です。 .NETの一部のバージョン(3.0および3.5など)では、CLRまたはそのCLRに関連付けられている既存のアセンブリを更新せずに、追加のフレームワークアセンブリが追加されました。

Windows.EXEファイルが配信されるPortableExecutable(PE)ファイル形式には、実行可能ファイルを説明し、ファイルを.NETファイルまたはネイティブWin32ファイルとして識別するヘッダーが含まれています。 Windowsが.NETファイルを実行しようとすると、このヘッダーが表示され、ユーザーに代わってCLRが自動的に呼び出されます。これが、.NETEXEファイルがWindows上でネイティブに実行されているように見える理由です。

わかりました、Monoはどのように機能しますか?

Monoは、Linux、Mac、およびその他のプラットフォームにCLRを実装します。 Monoランタイム(CLR)は、主にC言語で記述され、実行するように設計されたコンピューターシステムの機械語コードにコンパイルされたネイティブアプリケーションです。 Windowsと同様に、Monoランタイムは、使用しているオペレーティングシステムとマシンの種類に固有です。

Windowsの場合と同様に、Monoランタイム(CLR)は、.NET実行可能ファイルのCILバイトコードを、コンピューターが理解して実行できるネイティブコードにジャストインタイムでコンパイルします。このように、.NETファイルはWindowsと同様にLinuxにとっても「ネイティブ」です。

Monoを新しいアーキテクチャに移植するには、JIT/CLRを移植する必要があります。これは、ネイティブアプリケーションを新しいプラットフォームに移植するのと同じです。

LinuxまたはMacで.NETコードがどの程度適切に実行されるかは、実際には、これらのシステムでCLRがどの程度適切に実装されているかという問題にすぎません。理論的には、Mono CLRは、これらのシステムで.NETコードをWindowsで実行する.NETのMSバージョンよりもはるかに優れた方法で実行できます。実際には、MSの実装は一般的に優れています(すべての場合ではありませんが)。

CLRに加えて、Monoは、.NET Frameworkを構成する残りのライブラリ(アセンブリ)のほとんどを提供します。 Microsoftバージョンの.NETと同様に(実際にはもっとそうですが)、MonoアセンブリはCILバイトコードとして提供されます。これにより、Monoから* .dllまたは* .exeファイルを取得し、Windows、Mac、またはLinuxで変更せずに実行できます。CILはこれらのシステムのCLR実装の「ネイティブ」言語であるためです。

Windowsと同様に、MonoはCLRと関連するアセンブリの複数のバージョンをサポートしています。

非常に初期のバージョンのMono(1.2より前?)はCLR1.0または1.1のみをサポートしていました。 Monoは、独自の2.0バージョンになるまで、2.0フレームワークの大きなチャンクをサポートしませんでした。

バージョン2.4までのMonoバージョンは、CLR1.1とCLR2.0の両方のアプリケーションをサポートしていました。

Mono 2.6以降、CLR 4.0が追加されましたが、CLR2.0がデフォルトのままでした。

Mono 2.8以降、CLR 4.0がデフォルトになり、CLR1.1はサポートされなくなりました。

Mono 2.10は、引き続きCLR 4.0をデフォルトとして使用し、CLR2.0もサポートします。

実際の.NETと同じように(ただし、はるかに少ないケースですが)、ネイティブライブラリを呼び出すMonoアセンブリがいくつかあります。 System.DrawingアセンブリをMonoで機能させるために、MonoチームはLinuxプログラムを作成してLinux上のWin32APIのGDI +部分をシミュレートしました。このライブラリは「libgdiplus」と呼ばれます。ソースからMonoをコンパイルする場合、「mono」をビルドする前に、この「libgdiplus」ファイルをビルドする必要があることに気付くでしょう。 Win32APIのGDI +部分はすでにWindowsの一部であるため、Windowsでは「libgdiplus」は必要ありません。 Monoを新しいプラットフォームに完全に移植するには、この「libgdiplus」ライブラリも移植する必要があります。

.NETライブラリの設計がWindowsの設計に過度に影響され、MacやLinuxなどのシステムへの適合性が低い領域では、Monoチームが.NETフレームワークの拡張機能を作成しました。 Mono拡張機能もCILバイトコードであり、通常は.NETで問題なく機能します。

Windowsとは異なり、Linuxは通常.NET実行可能ファイルを検出せず、デフォルトでCLRを起動します。ユーザーは通常、「monoappname.exe」などと入力してCLRを直接実行する必要があります。ここで、「mono」はCLRを実装するアプリケーションであり、「appname.exe」は実行される.NETコードを含むEXEファイルです。

ユーザーが簡単に操作できるように、MonoアプリケーションはCLRを起動するシェルスクリプトでラップされることがよくあります。これにより、CLRがWindowsと同じように使用されているという事実が隠されます。 PEファイル形式を使用するファイルが検出されたときにCLRを起動するようにLinuxに指示することもできます。 PEファイル形式はもちろんCLR(Mono)がサポートしていないネイティブのWin32 Windows実行可能ファイルにも使用されるため、これは通常は行われません。

LinuxでPEランチャーを使用できなかった技術的な理由はありません。Linuxは、ネイティブのWindowsコード(Wineなど)またはCLR(Mono)を適切に理解するシステムを起動します。これは私の知る限りでは行われていません。

前後

「完全に管理された」コードに固執する.NETコード、つまり非.NETコードを呼び出さないコードは、すべてのプラットフォームのMonoで正常に機能するはずです。 LinuxとMacでは、Windows(コードがない)からコンパイルされた.NETアセンブリを日常的に使用しています。

また、Monoでコンパイルしたコードを取得して、Windowsの.NETで実行することもできます。私はMonoでコンパイルしたコードをクライアントに提供できますが、たとえば32ビットまたは64ビットのWindowsを使用している場合でも心配する必要はありません。クライアントには、コースに適切なバージョンの.NET(適切なCLR)がインストールされている必要があります。 CLR 2.0は非常に長い間使用されており、ほとんどすべてのWindowsユーザーがCLR2.0をインストールしていることは間違いありません。 Monoコンパイラやその他のコードもCIL実行可能ファイルであるため、必要に応じてWindowsで正常に実行されます。

モノラル互換性は十分に優れているため、ASP.NET MVCなどの実際のMicrosoftコードの大きなチャンクを、実際のMSバージョンの.NETから取得して、MacまたはLinuxで実行できます。一般に、Monoチームは、CLRと残りのフレームワーク(クラスライブラリ/アセンブリ)の両方を実装するという素晴らしい仕事をしてきました。

ASP.NET

Windowsでは、インターネットインフォメーションサーバー(IIS)は、CLRを呼び出して、Webアプリケーションの一部として.NETを実行する方法を知っています。 Linux/Macには、Apache Webサーバーと同様の機能を提供するApacheモジュール(mod_mono)があります。このアプリケーションはCで記述されており、新しいアーキテクチャにも移植する必要があります。

Porting Mono

この説明では、「ネイティブ」実行可能ファイルとして構築され、.NETアプリケーションを実行するシステムに存在する必要があるMonoの部分を特定しました。

  • CLR(JITコンパイラを含む)-一般にMonoとして知られています
  • libgdiplus(GDI + APIをネイティブにサポートしていないシステムの場合[Windowsのみ])
  • mod_mono(Apacheが.NETWebアプリケーションのCLRを呼び出せるようにするため)

これらの3つのコンポーネントは、クラスライブラリが追加されており、実行する必要のある.NET実行可能ファイルに対して「ネイティブ」に見える.NET環境を提供します。

それがMonoの仕組みです。

120
Justin

実際、Linux上のMonoで.NET.exeファイルを実行できます。これはWineを必要としません。実際、Monoはプログラムを.exeファイルにコンパイルします。このファイルは、LinuxのMonoで実行することも、Windowsの実行可能ファイルとして実行することもできます。

11
Greg Hewgill

Monoは、Microsoft .NET CLR(共通言語ランタイム)のオープンソース実装です。これは、ネイティブコードではなく、言語および機械語に依存しない中間言語であるCIL(Common Intermediate Language)で実行される.NETプログラムの一部を実行するものです。ランタイムはその中間コードを受け取り、それをマシンコードに変換します。

Monoの現在の状態では、.NETの主要部分(mscorlib.dll)を使用する.NETプログラムを取得して、Windowsだけでなく、Monoが実行されるすべての場所で実行できます。

3

ただし、Monoはオープンソースであり、完全な.NET実装であると信頼することはできません。一部のコントロールが機能していないため、アプリケーションが使用するP/Invokesにも注意する必要があります。たとえば、アプリケーションはwin32でMCI(マルチメディアコントローラインターフェイス)と通信します。しかし、私はモノラル書き込みGTK#アプリケーションも使用していましたが、上記の仲間のプログラマーが述べたように、再コンパイルなしで動作するWindowsアプリケーションも使用しました。つまり、モノラルはMicrosoftの.NETのオープンソースの代替であり、デフォルトではWinFormsまたはGtk#アプリケーションのいずれかを構築している場合、monoはコンパイルされ、ファイルごとに.exeアセンブリを作成します。もちろん、必要に応じて、.NETで行われるのとほぼ同じように、ダイナミックリンクライブラリ(DLL)を作成します。提案のために、いくつかのGtk#を書いてみてください(MonoDevelop IDEには、ステティックと呼ばれるGUIデザイナーが組み込まれています)。もちろん、monoは、作成できるWebサービスの優れた代替品になります。 .NETで、Apacheでホストできます(最近のLinuxホスティングはWindowsのものよりも安価であるため)Webサービスやその他のasp.netアプリは、Apacheに含まれている必要があるmod_monoモジュールを使用してApacheで動作します。

少し話題から外れていますが、私の経験から少しだけお話ししたいと思います。

2
milot

また、MoMAを確認することもできます(アプリケーションをWinからLinに移植することが目標の場合)。

Mono Migration Analyzer(MoMA)ツールは、.NetアプリケーションをMonoに移植するときに発生する可能性のある問題を特定するのに役立ちます。これは、プラットフォーム固有の呼び出し(P/Invoke)およびMonoプロジェクトでまだサポートされていない領域を特定するのに役立ちます。

MoMA

これは、Monoと.NET Framework3.5によってすでに実装されているBCLのタイプを比較するWebアプリです。

http://mono.ximian.com/class-status/2.0-vs-3.5/index.html

Michaelの対応をさらに進めるには、アプリをMonoランタイムで実行するには、Monoで再コンパイルする必要があると思います。例外が存在する場合があります。私はMonoを少しだけ試しただけで、常にソースを再コンパイルしました。 .NETアプリをMonoで直接実行しようとしたことはありません。

また、Mono1.9は.NET2.0に完全に準拠している必要があります。 Mono OliveとMoonlightは、.NET 3.0(WPFが少ない)とSilverlightの機能を追加することになっています。

0
user29439

それはあなたを助けるかもしれません、 MonoのC#コンパイラはどのように機能しますか? そして MonoC#コンパイラを理解する 本。

0
user727071