1

これが私が学ぼうとしているシナリオです:

  • ときどきイベントを発生させる DLL ファイルがあります。
  • ソース コード内の参照に DLL ファイルを追加することはできませんが、ディスク上で利用可能であり、プログラムは実行時にアクセスできます。
  • ランタイム用のアセンブリとして DLL ファイルをロードしました。
  • DLL からイベントをサブスクライブしようとしています (署名とパラメーターの形式を知っています)。プログラムでそれらを処理します。

Assembly は、2 つの引数を追加し、合計演算の結果を含むカスタム引数でイベントを発生させるメソッドを持つ単純な Dll です。DLL のコードは次のとおりです。

namespace Dll1
{
    public class Class1
    {
        public int c = 0;

        public void add(int a, int b)
        {
            c =  a + b;
            if (Added !=null)
                Added(this, new AddArgs(c));
        }

        public delegate void AddHandler(object sender, AddArgs e);

        public event AddHandler Added;

    }

    public class AddArgs : EventArgs
    {
        private int intResult;

        public AddArgs(int _Value) 
        {
            intResult = _Value;
        }

        public int Result
        {
            get { return intResult; }
        }
    }
}

次に、私のプログラムでは、Assembly.LoadFile を使用してその DLL をロードしました。プログラムには、ロードされたアセンブリからのイベントを処理するためのイベント ハンドラーを含むEventProcessorという別のクラスがあります。

namespace ConsoleApplication1
{
    class Program
    {
        static Type[] parmTypes;

        static void Main(string[] args)
        {
            Assembly asm = Assembly.LoadFile(@"C:\Projects\Dll1.Dll");
            Type typ = asm.GetType("DLL1.Class1", true, true);

            var method = typ.GetMethod("add");
            EventInfo eInfo = typ.GetEvents()[0];
            var obj = Activator.CreateInstance(typ);

            EventProcessor evProc = new EventProcessor();
            Type myTypeObj = evProc.GetType();
            MethodInfo myMethodInfo = myTypeObj.GetMethod("myEventHandler");

            Delegate d = Delegate.CreateDelegate(myTypeObj, myMethodInfo, true); // Error!
            eInfo.AddEventHandler(obj, d);

            method.Invoke(obj, new object[] { 1, 0 });
        }
    }
}

しかし、プログラムを実行すると、「型はデリゲートから派生する必要があります。パラメータ名:型」というエラーメッセージが表示されます。ここで何が間違っていますか?または、このシナリオを処理するためのより良い方法はありますか? 役立つ場合は、最後にイベント ハンドラー クラスも追加しました。

namespace ConsoleApplication1
{
    class EventProcessor
    {
        public void myEventHandler(object sender, AddArgs args)
        {
            Console.WriteLine("Event Received.");
        }
    }

    public class AddArgs : EventArgs
    {
        private int intResult;

        public AddArgs(int _Value)
        {
            intResult = _Value;
        }

        public int Result
        {
            get { return intResult; }
        }
    }
}

前もって感謝します。

4

1 に答える 1

1

問題は、ConsoleApplication1 に Dll1 への参照がないことです。両方のアセンブリで同じように構造化AddArgsしたとしても、それらはまだ異なるタイプであり、同じ意味で使用することはできません。

これに対する解決策は、アセンブリConsoleApplication1との両方で認識されている型を使用することですDll1。両方のアセンブリで同じ型を使用する必要があります。

CreateDelegate静的イベント メソッドに使用されるメソッドのオーバーライドも使用していました。インスタンス メソッドを接続しようとしているので、ターゲットも指定する必要があります。

于 2013-04-16T18:23:35.713 に答える