秀丸を閉じる時に実行する関数 (秀丸エディタ 8.98以上)

概要

C#で作成したdllは非同期処理などを含むことができますので、
「秀丸を閉じる」際などに、「スレッドを止める」あるいは「ファイルに書き込む」など必要な処理を行う必要があるような
dllを作成したいと思うこともあるでしょう。
秀丸エディタ 8.98以上ならば、COM呼び出しに対して、オブジェクト解放時にメソッドを指定して実行させることが出来ます。

public void ***() 型のメソッドを終了時用のメソッドとして定義

返り値と引数をobject型にし、実際の型を判定すればよいだけです。
決してobject型そのもののオブジェクトを返すわけではありません。
int型なりstring型なりの値を返すわけですが、どちらの型でもいけるよう、親クラス型となるobject型で宣言しておくことになります。

NET4COMServer.cs
using System;
using System.Runtime.InteropServices;

namespace NET4COMServer
{
    [Guid("BD55F2A6-9ED0-4F4F-9D37-E6B84BE63272")]
    public class NET4COMServer
    {
        public int add(int a, int b)
        {
            return a + b;
        }

        public void Dispose()
        {
            System.Diagnostics.Trace.WriteLine("Hidemaru NET5 COM Server Dispose");
        }
    }
}

呼び出し側

「setcomdetachmethod」と「keepobject」で、終了時のメソッドを指定しつつも、プロセスが終了するまでオブジェクトをキープすることとなります。
(※ keepobjectを記述しなかった場合は、マクロ終了時に自動的に、setcomdetachmethod で指定したメソッドが呼ばれます。)

NET4COMServer.mac
#obj = createobject( currentmacrodirectory + @"\NET4COMServer.dll", "NET4COMServer.NET4COMServer");
keepobject #obj, 1;
setcomdetachmethod #obj, "Dispose";
#add = member(#obj, "add", 100, 200);

// 秀丸のプロセスを閉じた際に、C#のDisposeが実行される。複数回マクロを実行した場合には秀丸を閉じた際にまとめて実行される。

呼び出し側

同じマクロを何度も実行した際、どんどんオブジェクトが蓄積されるのではなく、「(同じプロセスの)1つ前に生成したもの」は「Dispose」したい、といった場合には以下のようにすれば良いでしょう。

NET4COMServer.mac
// 前のマクロ実行時に「NET4COMServer.NET4COMServer」型のCOMオブジェクトが残っているならば、先にすべてリリースする。
// 20というのは適当な数。(1つのマクロで20個以上COMオブジェクトを作ることは極めてまれだろうという前提の数。)
#HmmacCOMRef = 1;
while(#HmmacCOMRef < 20) {
    // .NETのクラスはObjectを継承するため、必ずToStringを継承している。
    // 特別に上書きでもしていない限り、ユーザー定義のクラスなら、ToStringメソッドにより、名前空間+クラス名が文字列として帰ってくる。
    if (member(#HmmacCOMRef, "ToString") == "NET4COMServer.NET4COMServer") {
        releaseobject #HmmacCOMRef;
    }
    #HmmacCOMRef = #HmmacCOMRef + 1;
}

#obj = createobject( currentmacrodirectory + @"\NET4COMServer.dll", "NET4COMServer.NET4COMServer");
keepobject #obj, 1;
setcomdetachmethod #obj, "Dispose";
#add = member(#obj, "add", 100, 200);