VisualC#.NETで動的にDLLを読み込み実行する

VisualStudioでDLLを使用するとき、通常はプロジェクトの参照設定から目的のDLLを設定して使用すると思います。
しかし、決まったDLLではなくその都度DLLを使い分けたいときのように、動的にDLLを呼び出して使用したいときがある場合はDLLを直接呼び出す必要があります。

今回はDLLをプログラムコード中から動的に呼び出して使用する方法を紹介します。
※ここで言っているDLLは.NETで作成したDLLを指します。




実行するDLLの作成

今回確認するためのDLLを作成します。
内容はただ単に引数として受け取った文字列を「Hello 」の後に連結して返すという単純なものです。
コードは下記になります。

namespace ClassLibrary1
{
    public class Class1
    {
        public string Msg = "";
        
        public Class1(){
            Msg = "Hello ";    
        }

        public string Sample(string Str){
             return Msg + Str;
        }
    }
}

プログラムコードからDLLを読み込む

DLLを使用するために、まずアセンブリに読み込みます。
下記の例では、フォームに配置したテキストボックスからDLLのパスを取得してアセンブリにロードしています。

            // DLLファイルをアセンブリに読み込み
            System.Reflection.Assembly asm = System.Reflection.Assembly.LoadFrom(this.textBox1.Text);

読み込んだアセンブリから実行するモジュールを指定します。
下記の例では、モジュール名として読み込んだDLLのファイル名を指定しています。

            // モジュールを取得
            System.Reflection.Module mod = asm.GetModule(System.IO.Path.GetFileName(this.textBox1.Text));
            Type ty = mod.GetType("ClassLibrary1.Class1");

モジュールから、指定した名前空間、クラス名で検索を実行して対象の型を取得します。
下記の例では、名前空間、クラス名の「ClassLibrary1.Class1」で検索を実行しています。
名前空間、クラス名は、DLLで使用している名前空間とクラス名です。

            Type ty = mod.GetType("ClassLibrary1.Class1");

型情報からメソッドの属性を取得します。
その次に取得したメソッドの属性情報からパラメータ情報を取得します。

下記の例では、メソッドとして「Sample」を検索実行し、メソッドの属性を取得しています。
次に取得したメソッドの属性からパラメータ情報(パラメータの数だけ配列に格納)を取得します。

            // メソッドの引数情報を取得
            System.Reflection.MethodInfo mi = ty.GetMethod("Sample");
            System.Reflection.ParameterInfo [] pi = mi.GetParameters();

引数用のパラメータを作成します。
パラメータの数だけ型を準備しています。
下記の例では、パラメータは1つです。

            // 引数用のパラメータ作成 (パラメータの数だけ)
            Type[] types = new Type[]{pi[0].ParameterType};

指定したメソッドと準備したパラメータの型情報を検索してメソッド属性を取得します。

            // MethodInfoオブジェクトの取得
            System.Reflection.MethodInfo method = ty.GetMethod("Sample", types); // DLLのメソッド'Sample'

デリゲート呼び出しのためのオブジェクトを作成します。
先ほど名前空間、クラス名から検索して取得した対象の型情報をもとに作成しています。

            // オブジェクト生成
            object obj = System.Activator.CreateInstance(ty);

実行時にDLLの対象メソッドに渡す引数を設定します。
下記の例では、引数は1つのため文字列「World!」を設定しています。

            object [] Param = new object[]{"World!"};  // 引数'World!'

作成したオブジェクトとパラメータでデリゲート呼び出しを実行します。
これによりDLL内の対象のメソッドが指定した引数で実行されます。
下記の例では、返り値はResに格納されます。
Resの内容はメッセージボックスで表示しています。

            // DLL実行 (デリゲート呼び出し)
            var Res = method.Invoke(obj, Param); 
            // 結果を表示                
            MessageBox.Show((string)Res);

実行結果

下記のフォームに配置されているテキストボックスにDLLのパスを入力します。
サンプルでは「参照」ボタンで対象のDLLを選択するようにしています。

実際に今回作成したDLLを選択して実行した結果は下記になります。

正しくDLLが読み込まれ引数として渡した「World!」がDLL内で「Hello 」と連結され「Hello World!」となって返しています。

最後に

DLLをコード内で動的に読み込み実行することは手順が複雑で分かりにくいですが、状況に応じて必要なDLLを読み込んで実行することが出来ます。
あるフォルダに保存されているDLLを読み込んで実行するようなアドインのような使い方ができると思います。
ぜひ参考にしてください。

今回動作確認したサンプルは下記からダウンロードできます。

〔ガラクタ置き場〕