C#などで作った外部の「マネージドな.dll」の読み込み

  • 概要

    hmLoadCLRは、好きなフォルダに置いた自作のマネージドな.dllを(特に署名などもなく)突如自由に読みだして利用することが可能です。

    「C#」はもちろんのこと「VB.net」「C++/CLI」「F#」「JScript.net」などで作成したdllを読み込むことが出来ます。

    C#のソースから.dllを作成。

    最小限のサンプルとするため、わかりやすい構成としましょう。

    hmLoadCLR自体は、.NET Framework 4.0で構成されていますが、
    あなたが利用する.dllは、.NET Framework 4.6など、hmLoadCLRより新しいバージョンのアセンブリでも大丈夫です!!
    ここは普通の.NETの制限より非常に緩く出来ています。
    あなたのPCに入っている.NET Frameworkの一番新しいバージョンで作成しても問題ありません。

    • ファイル名は「TestSample.dll」
    • 名前空間は「TestNameSpace」
    • クラス名は「TestClass」
    • メソッドは「TestFuncNum」と「TestFuncStr」と「TestFuncMax」

    とします。

    コンパイルし、TestSample.dllといった名前にしたとしましょう。

    using System;
    
    namespace TestNameSpace
    {
        public class TestClass
        {
            public TestClass() { }
            public int TestFuncNum(int x)
            {
                return x + 3;
            }
    
            public String TestFuncStr(String s)
            {
                return s + s;
            }
    
            // 可変長引数
            public int TestFuncMax(params int[] a)
            {
                int max = a[0];
                for(int i=1; i<a.Length; ++i)
                {
                  if(max < a[i])
                    max = a[i];
                }
                return max;
            }
        }
    }
    
    

    loadするhmLoadCLRの例

    clr.System.Reflection.Assembly:LoadFromを利用することでアセンブリを読み込むことが出来ます。
    (clr.System.Reflection.Assembly.LoadFromでも同じです。)

    読み込めたマネージdllの内容は、clr以下に取り込まれます

    以下の内容をファイル名「loaddlltest.mac」とでもして保存してみましょう。
    文字コードはutf8で保存してください。

    #MNG = loaddll( hidemarudir + @"\hmLoadCLR.dll" );
    
    #_ = dllfuncw(#MNG, "DoString", R"MNG(
    
    -- 読み込めたら clr内にアセンブリとして読み込まれる
    clr.System.Reflection.Assembly:LoadFrom( hm.Macro.Var['currentmacrodirectory'] .. "/TestSample.dll" )
    
    local obj = clr.TestNameSpace.TestClass() -- clrに…
    result_num = obj.TestFuncNum(10)
    result_str = obj.TestFuncStr("あいう")
    
    hm.debuginfo(result_num)
    hm.debuginfo(result_str)
    
    result_max = obj.TestFuncMax(1, 100, -5, 101, 10)
    hm.debuginfo(result_max)
    
    result_max = obj.TestFuncMax(1, 10)
    hm.debuginfo(result_max)
    
    hm.Macro.Var['#rnum'] = result_max
    
    )MNG"
    );
    
    message(str(#rnum));
    
    freedll( #MNG );
    

    好きなフォルダに置く

    dllと.macつのファイルを好きなフォルダ(秀丸と一切関係ないフォルダでもよい)に置いて、
    「loaddlltest.mac」を適当に秀丸に登録して実行してみてください。
    .dllが読みだされ計算結果がダイアログに表示されるハズです。

    自作の個人的なディレクトリを、「.dll(アセンブリ)の置き場所」として認識させる

    アセンブリの.dllは本来配置場所が自由ではありません。
    これを特別に追加するため、「IronPythonなら、sys.path.append」、「IronRubyなら、$LOAD_PATH.push」があります。

    • package.path = "..." .. package.path

      これらと同様の機能を提供するため、hmLoadCLRのpackage.pathにパスを追加することで、
      該当のフォルダにあるアセンブリを自然な形で読み込むことが出来ます。
      パスは「;」で繋げていってください。

      特にC#など自作の.dllの中から、他の.dllを読み込んでおり、その両方を該当のディレクトリに入れている場合は、この設定が必須です。

    • load_assembly( "文字列" )

      最もよく利用する、「clr.System.Reflection.Assembly:Load( "文字列" )」のショートカット関数です。

    #MNG = loaddll( hidemarudir + @"\hmLoadCLR.dll" );
    
    #_ = dllfuncw(#MNG, "DoString", R"MNG(
    
    -- C:\aaaというフォルダを追加。セパレータとなる「;」を忘れないこと!!
    package.path = "C:/aaa;" .. package.path
    
    -- 読み込めたら clr内にアセンブリとして読み込まれる
    -- clr.System.Reflection.Assembly:Load( "TestSample" ) を短く書いたもの。
    load_assembly( "TestSample" )
    
    local obj = clr.TestNameSpace.TestClass() -- clrに…
    result_num = obj.TestFuncNum(10)
    result_str = obj.TestFuncStr("あいう")
    
    hm.debuginfo(result_num)
    hm.debuginfo(result_str)
    
    result_max = obj.TestFuncMax(1, 100, -5, 101, 10)
    hm.debuginfo(result_max)
    
    result_max = obj.TestFuncMax(1, 10)
    hm.debuginfo(result_max)
    
    hm.Macro.Var['#rnum'] = result_max
    
    )MNG"
    );
    
    freedll( #MNG );