C# マーシャリング

  • プロセスとは、基本的に、稼動中のアプリケーションを意味します。
  • マーシャリングとは、プロセスのオブジェクトを境界越しに処理できるようにする過程のことです。例えば、Word のオブジェクトを Excelスプレッドシート上に貼り付ける場合、プロセスの境界を越える必要があります。
  • すべてのプロセスは、アプリケーションドメインを持ち、さらに新規のアプリケーションドメインを作成することができます。アプリケーションドメインは、独立して開始、停止させることができます。これを利用して、例えば、別のプログラマが書いたライブラリを実行する場合、2番目のアプリケーションドメインに隔離することで、このライブラリがクラッシュしても、プログラム全体を停止させてしまわないようにすることができます。
namespace Marshaling
{
[Serialize]
public class Point
{
  public int X, Y;
  public Point (int x, int y) { this.X = x; this.Y = y; }
}

public class Shape : MarshalByRefObject // 参照渡しでマーシャリング
{
  public Point upperLeft;
  public Shape (int x, int y) { upperLeft = new Point(x,y); }
  public Show()
  {
    Console.WriteLine("{0} : {1},{2}",
      AppDomain.CurrentDomain.FiendlyName, upperLeft.X, upperLeft.Y);
  }
}

public class MyTest
{
  public static void Main()
  {
    ///// 現在のアプリケーションドメインの表示
    Console.WriteLine("AppDomain={0}", AppDomain.CurrentDomain.FriendlyName);

    ///// 新規アプリケーションドメインの作成
    AppDomain ad2 = AppDomain.CreateDomain("Shape Domain");

    ///// Shape オブジェクトの作成
    ObjectHandle oh = ad2.CreateInstance(
      "Marshaling", // アセンブリ名
      "Marshaling.Shape", // 型名
      false, // 大小文字の区別
      System.Reflection.BindingFlags.CreateInstance, // フラグ
      null, // バインダ
      new Object[] {3, 5}, // 引数
      null, null, null);

    Shape s1 = (Shape)oh.Unwrap();
    s1.Show(); // ShapeDomain : 3,5 と表示

    Point localPoint = s1.upperLeft; // マーシャンリングされ、コピーになる
    localPoint.X = 100; localPoint.Y = 100;
    Console.WriteLine("{0} : {1},{2}",
      AppDomain.CurrentDomain.FiendlyName, localPoint.X, localPoint.Y); // Marshaling.vshost.exe : 100,100 と表示
    
    s1.Show(); // ShapeDomain : やっぱり、3,5 と表示。
    ///// localPointの値の変更を反映させるには ...
  }
}
}

もし、クラス Point を以下のように変更すると、Point オブジェクトに対するプロキシが設定されて、プロパティはプロキシ経由でオリジナルの Point オブジェクトの値を変更します。つまり、Shape オブジェクトに対する変更が Point オブジェクトにも影響します。

public class Point : MarshalingByRefObject