Hi,
I just noticed that actually attaching the sample code might be an useful idea.
:-)
-----Ursprüngliche Nachricht-----
Von: Markus Schaber
Hi,
We have some existing C# classes using a custom event implementation which
calls delegates via reflection[1]. Now, when subscribing to the event exposed
by that class via IronPython, an ArgumentException is thrown:
Unbehandelte Ausnahme: System.ArgumentException: MethodInfo muss ein
MethodInfo-Laufzeitobjekt sein.
Parametername: this
bei System.Reflection.Emit.DynamicMethod.RTDynamicMethod.Invoke(Object obj,
BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo
culture)
bei System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
bei EventTest.Invoke(Object[] args) in
D:\playgroundSharpDevelop\IronPythonDelegateTest\Program.cs:Zeile 98.
bei ScriptExecutor.Main() in
D:\playgroundSharpDevelop\IronPythonDelegateTest\Program.cs:Zeile 37.
Script Finished
I attached a stripped down example program demonstrating this behavior.
Currently, we have a workaround of using a C# wrapper method as demonstrated in
the example code, but this is cumbersome, as we need to create a C# wrapper for
every exposed delegate type which uses that custom event implementation
internally, and we need to call that wrapper explicitly from the script.
I also want to avoid to rewrite the custom event implementation, as one of our
goals is to add the scripting capability in a non-intrusive way.
Now is there any way I can create a working MethodInfo object from pure
IronPython?
Best regards
Markus Schaber
[1] The main reason for this custom event implementation is that this
implementation internally keeps the references to the delegate target as weak
references, so that subscribing to that event alone does not prevent the object
from being collected.
--
___________________________
We software Automation.
3S-Smart Software Solutions GmbH
Markus Schaber | Developer
Memminger Str. 151 | 87439 Kempten | Germany | Tel. +49-831-54031-0 | Fax
+49-831-54031-50
Email: [email protected] | Web: http://www.3s-software.com CoDeSys
internet forum: http://forum.3s-software.com Download CoDeSys sample projects:
http://www.3s-software.com/index.shtml?sample_projects
Managing Directors: Dipl.Inf. Dieter Hess, Dipl.Inf. Manfred Werner | Trade
register: Kempten HRB 6186 | Tax ID No.: DE 167014915
using System;
using System.Reflection;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
public class ScriptExecutor
{
private const string SRC = @"
import clr
def handler(sender, event):
print 'Python handler: ', sender, ' with arg: ', event
eventtest.Foo += handler
def handler2(sender, event):
print 'Wrapped python handler: ', sender, ' with arg: ', event
wrapped_handler = eventtest.wrap(handler2)
eventtest.Foo += wrapped_handler
";
private static void Main()
{
try
{
ScriptEngine engine = Python.CreateEngine();
ScriptSource scriptSource =
engine.CreateScriptSourceFromString(SRC, "test.py");
engine.Runtime.LoadAssembly(typeof(ScriptExecutor).Assembly);
ScriptScope scope = engine.CreateScope();
var instance = new EventTest();
scope.SetVariable("eventtest", instance);
scriptSource.Execute(scope);
instance.Foo += StaticHandler;
instance.Foo += new ScriptExecutor().InstanceHandler;
instance.Invoke(instance, new FooEventArgs());
}
finally
{
Console.WriteLine("Script Finished");
Console.ReadLine();
}
}
private static void StaticHandler(object sender, FooEventArgs e)
{
Console.WriteLine("Handler in C# called.");
}
private void InstanceHandler(object sender, FooEventArgs e)
{
Console.WriteLine("Instance handler in C# called.");
}
}
public class FooEventArgs : EventArgs {}
public delegate void FooEventHandler(object sender, FooEventArgs e);
internal class Wrapper
{
internal readonly object Instance;
internal readonly MethodInfo Method;
internal Wrapper Next;
public Wrapper(object instance, MethodInfo method, Wrapper next)
{
Instance = instance;
Method = method;
Next = next;
}
}
public class EventTest
{
private Wrapper wrappers;
public event FooEventHandler Foo
{
add
{
wrappers = new Wrapper(value.Target, value.Method,
wrappers);
}
// remove left out as this is a simplified example.
remove { throw new NotImplementedException(); }
}
public void Invoke(params object[] args)
{
Wrapper wrapper = wrappers;
while (wrapper != null)
{
Console.WriteLine("Method: {0}", wrapper.Method);
Console.WriteLine("Instance: {0}", wrapper.Instance ??
"<null>");
if (wrapper.Method != null)
{
wrapper.Method.Invoke(wrapper.Instance, args);
}
wrapper = wrapper.Next;
}
}
public FooEventHandler wrap(FooEventHandler pyHandler)
{
return (o, e) => pyHandler(o, e);
}
}
_______________________________________________
Ironpython-users mailing list
[email protected]
http://mail.python.org/mailman/listinfo/ironpython-users