I am trying to use C# classes from python, using python.net on mono / ubuntu.
So far I managed to do a simple function call with one argument work. What I am now trying to do is pass a python callback to the C# function call.
I tried the following variations below, none worked. Can someone show how to make that work?
// C# - testlib.cs
class MC {
    public double method1(int n) {
        Console.WriteLine("Executing method1" );
        /* .. */
    }
    public double method2(Delegate f) {
        Console.WriteLine("Executing method2" );
        /* ... do f() at some point ... */
        /* also tried f.DynamicInvoke() */
        Console.WriteLine("Done executing method2" );
    }
}
Python script
import testlib, System
mc = testlib.MC()
mc.method1(10) # that works
def f():
    print "Executing f"
mc.method2(f)  
# does not know of method2 with that signature, fair enough...
# is this the right way to turn it into a callback?
f2 = System.AssemblyLoad(f) 
# no error message, but f does not seem to be invoked
mc.method2(f2)              
                Try to pass Action or Func instead of just raw function:
I used IronPython here (because right now I don't have mono installed on any of my machines but according of Python.NET documentation  I think it should work
Actually your code is almost ok but you need to import Action or Func delegate depends on what you need.
python code:
import clr
from types import *
from System import Action
clr.AddReferenceToFileAndPath(r"YourPath\TestLib.dll")
import TestLib
print("Hello")
mc = TestLib.MC()
print(mc.method1(10))
def f(fakeparam):
    print "exec f" 
mc.method2(Action[int](f))
This is a console output:
Hello
Executing method1
42.0
Executing method2
exec f
Done executing method2
C# code:
using System;
namespace TestLib
{
    public class MC
    {
        public double method1(int n)
        {
            Console.WriteLine("Executing method1");
            return 42.0;
            /* .. */
        }
        public double method2(Delegate f)
        {
            Console.WriteLine("Executing method2");
            object[] paramToPass = new object[1];
            paramToPass[0] = new int();
            f.DynamicInvoke(paramToPass);
            Console.WriteLine("Done executing method2");
            return 24.0;
        }
    }
}
I read docs for Python.net Using Generics again and also found this Python.NET Naming and resolution of generic types look like you need to specify parameter type explicitly
quote from there:
a (reflected) generic type definition (if there exists a generic type definition with the given base name, and no non-generic type with that name). This generic type definition can be bound into a closed generic type using the [] syntax. Trying to instantiate a generic type def using () raises a TypeError.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With