Antoine.st Bk Dot Net Wrapper

Becky 2 PlugIn Wrapper for .NET

What is this?

プラグインの宿命といいますか、B2 用のプラグインもやっぱり関数の Export を要求します。.NET アプリケーション (C#、Visual Basic .NET) では、かなり特殊なことをやらないと関数の Export ができません。そこで、MC++ (Managed C++) を利用して、.NET のクラスライブラリ (プラグインとして作成されたもの) を呼び出すプラグインを作ってみました。

Implementation

.cpp 側のポイントは、こんな感じです。単にアセンブリをロードし、メソッドを Invoke するだけ。とっても簡単。相変わらず手抜きなので、.NET のアセンブリ、クラス名は .ini ファイルから読み込むようにしてます。決まったフォルダ (たとえば、\Plugins\.net\) に配置して、そこから読み込むようにするなんてのもいいかも。

int WINAPI BKC_OnStart() は、B2 のプラグイン仕様を満たすための Export 関数のひとつです。他の Export 関数も同様に実装します。


  Assembly* GetAssembly(char* szPath)
  {
    return Assembly::LoadFrom(szPath);
  }

  Type* GetPlugInType(Assembly* asmbly, char* szClass) 
  {
    return asmbly->GetType(szClass);
  }

  Object* GetPlugInObject(Type* dotnetPlugInType)
  {
    return Activator::CreateInstance(dotnetPlugInType);
  }

  int Invoke(String* methodName, Object* args[])
  {
    Assembly* asmbly = GetAssembly(_szPath);
    Type* dotnetType = GetPlugInType(asmbly, _szClass);
    Object* dotnetObj = GetPlugInObject(dotnetType);
    Object* returnValue = 
      dotnetType->InvokeMember(methodName, 
                               BindingFlags::InvokeMethod, 
                               NULL, 
                               dotnetObj, 
                               args);
    return Convert::ToInt32(returnValue);
  }

  int WINAPI BKC_OnStart()
  {
    return Invoke("BKC_OnStart", NULL);
  }

で、呼び出される .NET クラスの方はこんな感じで。各メソッドは BaseClass の中で virtual 宣言してあるので、クラスを継承して必要なメソッドだけを実装します。


  public class BaseClass {

    public virtual int BKC_OnStart() {
      return 0;
    }
  }

  public class DerivedClass : BkDotNetPlugIn.BaseClass {

    public override int BKC_OnStart() {
      MessageBox.Show("OnStart in Derived Class.");
      return base.BKC_OnStart();
    }
  }

Any comments


name: comments: