我已經walkthru stackoverflow和msdn的很多帖子和嘗試他們的解決方案,但我仍然無法得到它的作品,所以我希望任何人都可以幫助我。非常感謝您動態加載DLL與AddeventHandler
首先我還沒有加入
MethodInfo mi = instance.GetType().GetMethod(sMethodName, myBindingFlags);
Delegate del = Delegate.CreateDelegate(typeof(ErrorEventHandler), null, mi);
直接調用
ei.AddEventHandler(instance, handler);
那麼錯誤是
對象類型 'xxxxErrorEventHandler' 不能轉換爲類型 'xxxxErrorEventHandler'。
然後我按照一些後修改我的代碼如下,然後引發錯誤時createDelegate方法
DLL:
public class ErrorEventArgs : EventArgs
{
public string ErrorMsg;
}
public interface IClassA
{
bool Run();
}
public class ClassA : IClassA
{
public delegate void ErrorEventHandler(object sender, ErrorEventArgs data);
public event ErrorEventHandler OnErrorHandler;
public void OnError(object sender, ErrorEventArgs data)
{
if (OnErrorHandler != null)
{
OnErrorHandler(this, data);
}
}
public bool Run()
{
// do something inside DLL
ErrorEventArgs data = new ErrorEventArgs();
data.ErrorMsg = "Hello World";
OnError(this, data)
}
}
EXE:
public delegate void ErrorEventHandler(object sender, ErrorEventArgs data);
void main()
{
Assembly assembly = Assembly.LoadFile("myDLL.dll");
Type[] types = assembly.GetTypes();
for (int i = 0; i < types.Length; i++)
{
Type type = assembly.GetType(types[i].FullName);
if (type.GetInterface("myDLL.IClassA") != null)
{
object obj = Activator.CreateInstance(type);
if (obj != null)
{
MethodInfo methodInfo = obj.GetType().GetMethod("Run");
ErrorEventHandler handler = foo;
BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public;
EventInfo ei = instance.GetType().GetEvent("OnErrorHandler", myBindingFlags);
MethodInfo mi = instance.GetType().GetMethod("Run", myBindingFlags);
*// System.ArgumentException raised here
// Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.*
Delegate del = Delegate.CreateDelegate(typeof(ErrorEventHandler), null, mi);
ei.AddEventHandler(instance, del);
bool Result = methodInfo.Invoke(instance, null);
}
}
}
public void foo(object sender, ErrorEventArgs data)
{
Console.WriteLine("In Foo!");
}
}
回覆樓層1
嗨漢斯,非常感謝您的回答,我遵循您的建議修改我的代碼。如果回調函數聲明這樣
private static void Callback(string msg)
和ClassA的事件中也聲明這樣
public delegate void ErrorEventHandler(string msg);
public event ErrorEventHandler OnErrorHandler;
public void OnError1(string msg)
{
if (OnErrorHandler != null)
{
OnErrorHandler(msg);
}
}
工作正常,但如果聲明它像以前一樣
private static void Callback(object sender, ErrorEventArgs data)
它出現錯誤「無法綁定到目標方法,因爲它的簽名或安全透明與代理類型不兼容。」當運行
Delegate del = Delegate.CreateDelegate(ei.EventHandlerType, null, mycallback);
你知道爲什麼,順便說一句,真的非常感謝你的幫助。
錯誤,如果在EXE側像修改後的代碼:
.......
BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public;
EventInfo ei = instance.GetType().GetEvent("OnErrorHandler", myBindingFlags);
MethodInfo mi = instance.GetType().GetMethod(sMethodName, myBindingFlags);
var mycallback = typeof(ModuleManager).GetMethod("Callback", BindingFlags.Static | BindingFlags.NonPublic);
Delegate del = Delegate.CreateDelegate(ei.EventHandlerType, null, mycallback);
ei.AddEventHandler(instance, del);
.......
private static void Callback(object sender, ErrorEventArgs data)
{
Console.WriteLine("In Callback!");
}
嗨漢斯,謝謝你的幫助。我已經測試過,部分代碼正在工作,但仍然存在一些問題。我描述了問題線程中的細節。你能幫忙看看。謝謝 – user3440306
在我看來,你通過在Callback()方法中使用ErrorEventArgs再次犯了同樣的錯誤。你沒有正確的類型,所以你必須使用* object *來代替。如答案中所述,您必須在方法中使用反射來獲取* data *成員值。 –
感謝您的幫助和答覆。我得到了你的答案。非常感謝 – user3440306