ものがたり(旧)

atsushieno.hatenablog.com に続く

monoとグローバル アセンブリ キャッシュ

うーむ、すっかりmonoの簡単なイントロダクションをするページではなくなってしまった。というわけで、今日はmono specificな技術ネタを書こう。

今日はmonoのグローバル アセンブリ キャッシュとインストール構成について。

グローバル アセンブリ キャッシュ(以下GAC)というのは、Javaで言うならjre/lib/extのようなもので(何て乱暴な説明!)、.NETプログラムの多くが使う共通のアセンブリを1箇所にまとめたもの、ということになる。.NETのGACについては、何はなくともこれを読むべし(いや、GACを全く知らない人が、僕がこれから書く話を読んでも意味ないと思うけど)。

Javaを使ったことのある人なら分かると思うけど、Java仮想マシンは1つのマシンに複数インストールすることができる。Microsoft.NETは、1つのマシンに複数バージョンの.NETをインストールすることはできるが、同一のバージョンの.NET環境を複数インストールすることはできない。Monoは、どちらかと言えばJavaモデルになっていて(MS.NETではそれはmscoree.dllの設計上出来ないんですねー)、アプリケーションを使用する環境と、クラスライブラリをhackするときの環境を使い分けることもできる。*1

ただし、monoのインストールモデルは、複数バージョンをフルセットで提供するスタイルになっている*2。どういうことかというと、1つのmonoのインストール ベースの中には、バージョン1.0とバージョン2.0の両方が含まれているのだ。Javaで言うなら、1.3と1.4が一緒に入ってるようなものだ。

結果的に、それぞれのインストールベースごとにGACが存在することになる。

このインストールモデルは、結果としてMS.NETのような複数バージョンの併存を可能にしている。Javaとの違いをあらわす典型的な例がside-by-side実行で(これは実はmono 1.1にならないと実現しないのだけど)、アセンブリのproveは、アセンブリからPEヘッダから読み取られて、対象となるmscorlibのバージョンを決定するときに、そのインストールベースの中で、どのバージョン(1.0と2.0)を使用するか、で決まってくる。こうやって、MS.NETのようなアセンブリのロードが実現されているわけだ。

MS.NETは、PE headerをそのままWindows実行ファイルとしてCLRローダを呼び出して実行するのだけど、Monoではmono(windowsではmono.exe)が環境を決定する。

GACまわりはまだまだ書ける話が多い。「インサイドmono」とかやって吉松さんのまねしてみようかしらん。(無理無理w

*1:逆に言えば、それ以外の用途で複数インストールする意味はほとんど無いかも。

*2:いや、パッケージング ディストリビューションについては、まだポリシーが決まっていないけど