特集

Linuxで動く.NET環境「Mono 1.0」の実力(後編)

―― LinuxでASP.NET Webアプリケーションを動かす ――

株式会社ピーデー
川俣 晶
2004/10/20
Page1 Page2 Page3 Page4

 前編では、Monoが生まれた背景や、Monoのインストール方法、Monoで用意されているC#コンパイラとVB.NETコンパイラなどについて解説した。後編となる今回では、LinuxとWindowsの異なる2つの環境でコンパイルした実行ファイルの互換性や実行速度の検証、そしてMono上でのASP.NET Webアプリケーションの動作についてレビューする。

バイナリの互換性を検証する

 C#やVisual Basic .NET互換のMonoBASICコンパイラにより生成された実行ファイル(.exeファイル)が、Linux上で直接実行できないことは前編で説明した。実行には、monoコマンドを経由して起動する必要がある。なぜ、コンパイラは直接起動できる実行ファイルを生成しないのだろうか。その方がずっと使い勝手が良さそうに思えるが、それを行わないことに、どのような理由があるのだろうか。

 その理由は、Monoには.NET Frameworkとのバイナリ・レベルでの互換性がある、という点にある。つまり、MonoのC#コンパイラで生成した実行ファイルは、マイクロソフトの.NET Frameworkで実行でき、マイクロソフトのC#コンパイラで生成した実行ファイルは、Monoのmonoコマンドによって実行できるということである。このように書くと、かなりウソくさい印象も受ける。ソフトウェア開発関連技術で、このような「どこでも実行できる(例えば「Write Once, Run Anywhere!」というような標語で示されるもの)」という長所を訴えた技術は、恐らく成功例よりも失敗例の方がはるかに多いだろう。しかも、成功例にしても、決して楽に実現できたわけではないし、異種環境間ではトラブルが起こりやすい傾向にあるように感じる。

 しかし、Monoで実現されている互換性は、理想よりもリアリズムを追求した互換性だといえる。理想とは、まさに1つの実行ファイルがどのような環境でも動作することにあるが、それを完全に達成することは不可能と思って間違いないと思う。現実に達成できないが故に、それは理想と呼ぶにふさわしい。理想の高尚さは、多くの人々を魅惑し、それを達成する多くの努力が払われる。しかし、リアリズムに立脚して見れば、払われた労力の膨大さに比して、得られる成果はあまりに小さい。本筋から外れるので詳しい理由は書かないが、経験からいっても、理屈からいっても、それは当然の帰結といえる。

 では、リアリズムに立脚すれば互換性など意味がないのかといえば、それは違う。リアリズムが目指すものは、白黒をはっきり付けることよりも、どちらにも偏らないバランスの良さである。つまり、異なる環境間でも共通に使用できる技術に互換性を持たせず、共用しないのはあまりに無駄ということである。例えば、Monoが生成する実行ファイルが、マイクロソフト製品が生成する実行ファイルと同等であれば、たとえ実行できなくても、Windows上の便利なツールで実行ファイルを扱うこともでき、そこには明確なメリットがある。実際、本稿を書いている筆者のパソコンでは、ついさっきWindows上で動くReflectorというツールで、Mono C#コンパイラによる実行ファイルを調べたばかりである(Reflectorについては「.NET Tools:.NET逆コンパイラとコードを難読化するDotfuscator」を参照)。

 つまり、Monoと.NET Frameworkの互換性とは、そのような文脈でとらえるべきものである。あらゆる実行ファイルがどちらの環境でも実行できるという高尚ではあるがコスト・パフォーマンスの悪い「理想」を目指したものでは決してなく、共通化して問題ないものは共通化して共用しましょう、というリアリズムの文脈でとらえるべきものである。

■Monoの実行ファイルをWindows上で実行する

 さて、基本的なコンソール・アプリケーション程度であれば、両者の間には高い互換性があり、1つの実行ファイルを問題なく実行できる。ECMA-335 Common Language Infrastructure(CLI)で規定される範囲内の機能、クラス・ライブラリを用いて作成されたプログラムであれば、たいていの場合、どちらでも実行できるプログラムになると思ってよいだろう。では実際に、Mono C#コンパイラで生成した実行ファイルをWindowsに転送して.NET Framework 1.1上で実行してみよう。

 以下は前編のprime.exeをWindows 2000 Professionalにインストール済みの.NET Framework 1.1上で実行した例である。10までの素数をリストさせている。

C:\mono>mono\prime.exe -l 10 1
2
3
5
7

 見事、問題なく実行できた。

 比較のために、マイクロソフト製のC#コンパイラで生成した実行ファイルも同じ設定で実行させてみた。結果は同じである。

C:\mono>ms\prime.exe -l 10 1
2
3
5
7

 この程度では動作が本当に同じであるか不安を感じる読者もいるかもしれない。念のため、両方の実行ファイルで100000までの素数をリストさせ、結果を比較してみよう。出力をファイルにリダイレクトし、Windowsに付属するfcコマンド(ファイル比較ツール)で両者の一致を確認している。

C:\mono>ms\prime.exe -l 100000 1 > ms_result.txt

C:\mono>mono\prime.exe -l 100000 1 > mono_result.txt

C:\mono>fc ms_result.txt mono_result.txt
ファイル ms_result.txt と MONO_RESULT.TXT を比較しています
FC: 相違点は検出されませんでした

 これで、この2つの実行ファイルは同じ結果を出力することが分かった。では、どちらの実行ファイルも、まったく同じ内容なのだろうか。そうではないらしい。少なくとも、実行ファイルのサイズはまったく異なっている。それぞれのサイズは以下のようになった。

Mono C#コンパイラによる実行ファイル 4608bytes
マイクロソフト製C#コンパイラによる実行ファイル 16384bytes

 もちろん、実行ファイルの内容は同じでないが、使用したソース・コードは完全に同じである。先に示したReflectorを使って両者の逆アセンブル・コードを比較したが、完全に同じではないことを確認した。恐らく機能的には同等と思われるが、実際に実行されるコード部分に限ればMono C#コンパイラの方がややコンパクトなコードを生成している。

 ファイル・サイズが数倍の差にもなっている理由は、マイクロソフト製C#コンパイラが生成した実行ファイルにのみ「00」で満たされた多くの領域があるためである。何のために用意されている領域か筆者には分からないが、そのような領域を持たない実行ファイルも実行できることから考えて、恐らくプログラムの実行には必須ではないものだと思う。

 さて、ここではMono C#コンパイラによる実行ファイルを.NET Framework上で実行させたが、逆はどうだろうか。

■Windowsの実行ファイルをLinux上で実行

 2つの実行ファイルをLinux上に移して実行した結果は以下のとおりである。なお、「mono/prime.exe」はMono C#コンパイラによるもの、「ms/prime.exe」はマイクロソフト製C#コンパイラによるものである。

[autumn@lh-3c0frsgnj0nd mono]$ mono ms/prime.exe -l 10 1
2
3
5
7
[autumn@lh-3c0frsgnj0nd mono]$ mono mono/prime.exe -l 10 1
2
3
5
7
[autumn@lh-3c0frsgnj0nd mono]$ mono mono/prime.exe -l 100000 1 > mono_result.txt
[autumn@lh-3c0frsgnj0nd mono]$ mono ms/prime.exe -l 100000 1 > ms_result.txt
[autumn@lh-3c0frsgnj0nd mono]$ diff ms_result.txt mono_result.txt
[autumn@lh-3c0frsgnj0nd mono]$

 以上のとおり、マイクロソフト製C#コンパイラが生成した実行ファイルを、monoコマンドを用いてLinux上で実行することができた。また、100000までの素数リストの内容も、Mono C#コンパイラの出力と完全に一致することが2ファイルの相違を検出するdiffコマンド(ファイル比較ツール)を用いて確認できた(diffコマンドは相違点を出力しないことで一致を示している)。


 INDEX
  [特集]Linuxで動く.NET環境「Mono 1.0」の実力(前編)
     1.WindowsとLinuxとを結ぶ「Mono」
     2.Monoが生まれた背景
     3.Monoの機能とインストール
     4.C#コンパイラとVB.NETコンパイラ
  [特集]Linuxで動く.NET環境「Mono 1.0」の実力(後編)
   1.バイナリの互換性を検証する
     2.環境間の相違と対策/Monoと.NET Frameworkとの速度比較
     3.XSPを用いたASP.NET
     4.Apacheを用いたASP.NET
 


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間