動的にDLLファイルのクラスメソッドを呼び出す (Reflectionを用いたアセンブリの動的呼び出し)

Reflectionを用いてアセンブリの動的呼び出しを利用して、動的にDLLファイルのクラスメソッドを呼び出すコードを紹介します。

概要

アセンブリのクラスメソッド(DLLファイル)を動的に呼び出したい場合があります。C++,DelphiではDLL関数にエクスポート関数を定義し、LoadLibrary関数で動的にDLLをインポートできます。C#でも同様の方法は使えますが、Reflection(リフレクション)機能を用いるとクラスメソッドまで簡単に呼び出せます。

まず、プロジェクトの新規作成でWinformプロジェクトを新規作成します。次に、ソリューションエクスプローラウィンドウで右クリックをしポップアップメニューの[追加]メニューの[新しい項目]をクリックしプロジェクトを追加します。追加するプロジェクトは、クラスライブラリプロジェクトにします。


プロジェクトが追加されるとソリューションエクスプローラウィンドウは下図のようになります。

クラスライブラリプロジェクトでビルドされた結果のDLLがWinFormアプリケーションと同じ位置に出力されるようにWinForm側のプロジェクトからクラスライブラリを参照に追加します。
(ここは、プロジェクトのプロパティ設定で出力先ディレクトリを指定してもよいですし、手でその都度コピーする方法をとっても構いません。WinFormプロジェクトの実行ファイルと同じディレクトリにDLLファイルが配置されるようにします。)

プログラムコード

以下のコードを実装します。

CalcClass.cs (呼び出されるライブラリ側)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SimpleLib
{
  public class CalcClass
  {
    public int Add(int a, int b)
    {
      return a + b;
    }
  }
}

Form1.cs (呼び出し側)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;

namespace DynamicLoad
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
    }

    private void button1_Click(object sender, EventArgs e)
    {
      Assembly asm = Assembly.Load("SimpleLib");
      Type myType = asm.GetType("SimpleLib.CalcClass");
      MethodInfo myMethod = myType.GetMethod("Add");
      Object obj = Activator.CreateInstance(myType);
      object ret = myMethod.Invoke(obj, new Object[] { 1, 2 });

      textBox1.Text = Convert.ToString(ret);
    }

    private void button2_Click(object sender, EventArgs e)
    {
      Assembly asm = Assembly.LoadFrom("SimpleLib.dll");
      Module mod = asm.GetModule("SimpleLib.dll");
      System.Type type = mod.GetType("SimpleLib.CalcClass");
      if (type != null) {
        Object obj = Activator.CreateInstance(type);

        Type[] types = new Type[2];
        types[0] = typeof(int);
        types[1] = typeof(int);
        MethodInfo addMethod = type.GetMethod("Add", types);
        object ret = addMethod.Invoke(obj, new object[2] { 1, 2 });

        textBox1.Text = Convert.ToString(ret);
      }
    }
  }
}

説明

Button1 はアセンブリ名を使って動的呼び出しをする場合のコード、Button2はファイル名を使って動的呼び出しをする場合のコードになります。

Button1

Assembly asm = Assembly.Load("SimpleLib");
でアセンブリ名を指定してアセンブリを読み込みます。
Type myType = asm.GetType("SimpleLib.CalcClass");
でクラスの型を取得します。
MethodInfo myMethod = myType.GetMethod("Add");
でクラスの型からメソッド情報を取得します。
Object obj = Activator.CreateInstance(myType);
クラスの型からクラスのインスタンスを作成します。
object ret = myMethod.Invoke(obj, new Object[] { 1, 2 });
作成したインスタンスからメソッドを呼び出します。
textBox1.Text = Convert.ToString(ret);
メソッドの戻り値をテキストボックスに表示します。

Button2

Assembly asm = Assembly.LoadFrom("SimpleLib.dll");
でアセンブリのファイル名を指定してアセンブリを読み込みます。
Module mod = asm.GetModule("SimpleLib.dll");
でモジュールを取得します。
System.Type type = mod.GetType("SimpleLib.CalcClass");
でモジュールからクラスの型を取得します。
  Object obj = Activator.CreateInstance(type);
クラスの型からクラスのインスタンスを作成します。
  Type[] types = new Type[2];
  types[0] = typeof(int);
  types[1] = typeof(int);
  MethodInfo addMethod = type.GetMethod("Add", types);
メソッドの引数を定義し、メソッド情報を取得します。
  //MethodInfo addMethod = myType.GetMethod("Add");
としてもよいです。
  object ret = addMethod.Invoke(obj, new object[2] { 1, 2 });
作成したインスタンスからメソッドを呼び出します。
  textBox1.Text = Convert.ToString(ret);
メソッドの戻り値をテキストボックスに表示します。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2010-06-24
iPentec all rights reserverd.