ソフトの砂場(Mono)

最終更新日:2003年11月9日


2003年11月2日

.NET互換環境であるmonoで遊んでみました。

これは、ふつ〜Linux上で動かすのだろうと思いますが、Windows版もあるので、それをインストールして試してみました。が、苦労するハメに。

まずはmonoのダウンロードページから、mono-0.28-win32-1.exeをもらってきてインストールしました。インストーラになっているので、これは簡単です。で、次のようなおきまりのソースコードをC#で書いてmcsコマンドでコンパイルしようとしてみると、assertion failedで実行できません。TimeZone関係のエラーなので、環境変数TZを設定すれば?など試してみましたがうまくいきません。

using System;

class Hello {
  public static void Main() {
    Console.WriteLine("Hello, World!");
  }
}

ダウンロードページを見ていると、cygwinなしで動くのはこちら、と書いてあるリンクがあります。が、リンクが切れているんですよね。まあ、ということは、cygwinが必要なのでしょう。cygwinをインストールしてその中から実行してみると、確かに動作が変わります。libglib-2.0-0.dllがないとか言われるので、monoのbinに加えてlibディレクトリにパスを通してみると、今度はmscoree.dllがないとのこと。調べてみると、これはマイクロソフトが出している.NET Frameworkに含まれるファイルの模様。互換環境のハズなのに純正のファイルがいるとはどういうこと?という疑問はありますが、そんなことを言っていては先に進まないので、あきらめて.NET FrameworkとLanguage Packをインストール。.NET Framework SDKもありましたが、これは今のところなくてもよさそう。

これをインストールすると、ついにコンパイルは通るようになり、実行形式ファイルはできました。拡張子はexeなんですね。次にこれをmonoコマンドで実行しようとすると、今度は、

$ mono hello.exe
The assembly corlib.dll was not found or could not be loaded.
It should have been installed in the `C:/cygwin/home/duncan/install/lib' directory.

というメッセージが出ます。corlib.dllはmonoのlibディレクトリにあって、環境変数MONO_PATHもセットしているのですが、ファイルを見つけられないみたい。

ふと思いついて、実行形式ファイルをcygwinではなくWindowsのコマンドプロンプトから直接実行してみると、おお、ちゃんと実行できるではないですか。が、冷静になって考えてみると、これはきっとマイクロソフトの.NET Frameworkの実行環境を使っているに違いないのですね。まあ、それでも、monoで作ったファイルなので、実行できたのは一歩前進なのですが。

再度monoコマンドを動かそうと思い、duncanって誰? と思いつつも、面倒なので指定されたディレクトリにbinとlibディレクトリを全部コピーしてみると、ようやく実行できました。ただ、Javaのクセで拡張子なしで実行しようとするとエラーになりましたが。

ついでに、メッセージを日本語にしてみると、出力が文字化けしてしまいます。最初はcygwinの問題かと思いましたが、シェルスクリプトからは日本語を出力できるのでそうではないと思い、調べてみるとコンパイラのオプションでコードページを指定できることが判明。いつもの調子でMS932と書いたのですが、そうではなく番号だけでいいことがわかりました。次のような感じ。

$ mcs -codepage:932 hello2.cs

実行時はコードページの指定は不要です。ようやくこれで最低限の準備はできましたが、疲れ切ってしまったので今回はこれでおしまい。


2003年11月3日

昨日の試行錯誤の中で、monoで作成した実行形式をWindowsのコマンドプロンプトから実行できた件について、もう少し調べてみました。[1]によるとmonoのFileInfoの実装にはバグがあって.NET Frameworkと動作が違うということなので、簡単なプログラムで試してみました。ソースコードは[1]に載っていたものを簡略化したこんなの。

using System;
using System.IO;

public class FileInfoDemo {
        public static void Main(String[] args) {
                foreach (string x in args) {
                        Console.WriteLine("files in {0}", x);
                        DirectoryInfo dir = new DirectoryInfo(x);
                        FileInfo[] files = dir.GetFiles();
                        foreach (FileInfo s in files) {
                                Console.WriteLine(s);
                        }
                }
        }
}

これは指定されたディレクトリ内のファイルを一覧表示するものですが、.NET Frameworkではファイル名だけが表示されるのに対して、monoではフルパスで表示されるそうです。で、実行してみると、コマンドプロンプトから実行するとファイル名だけが表示され、monoを使って実行するとフルパスで表示されたので、昨日の予想はそのとおりだったようです。バグもたまには役立つということでしょうか。いつまでこの方法が使えるか分かりませんけどね。


2003年11月9日

ソースコード内に日本語を(日本語に限りませんが)含む場合、前々回はmcsのオプションで-codepageを指定しましたが、byte order markを含むUnicodeで書けば自動判別するということのようです。なお、デフォルトは、latin-1ということでした。

そこで、byte order markを含むutf-8でソースコードを保存してみると(バイナリエディタで見ると、ファイル先頭の3バイトが ef bb bf になる)、-copdepageオプションなしでmcsコマンドを実行しても正しく出力されることがわかりました。


参考文献

  1. H. J. Schnöig and E. Geschwinde, Mono Kick Start, SAMS, 2004

[ソフトの砂場の目次] [ホーム]