简体   繁体   English

如何将python回调传递给c#函数调用

[英]How to pass python callback to c# function call

I am trying to use C# classes from python, using python.net on mono / ubuntu. 我正在尝试使用python中的C#类,在mono / ubuntu上使用python.net。

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. 我现在要做的是将python回调传递给C#函数调用。

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 Python脚本

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: 尝试传递ActionFunc而不仅仅是原始函数:

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. 我在这里使用IronPython(因为现在我没有在我的任何机器上安装单声道,但根据Python.NET 文档,我认为它应该工作实际上你的代码几乎没问题,但你需要导入ActionFunc委托取决于什么你需要。

python code: python代码:

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: C#代码:

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 我再次阅读Python.net 使用Generics的文档,并发现这个Python.NET命名和泛型类型的解析看起来像你需要明确指定参数类型

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. 尝试使用()实例化泛型类型def会引发TypeError。

It looks like you should define your Delegate explicitly: 看起来您应该明确定义Delegate:

class MC {
    // Define a delegate type
    public delegate void Callback();

    public double method2(Callback f) {
        Console.WriteLine("Executing method2" );
        /* ... do f() at some point ... */
        /* also tried f.DynamicInvoke() */
        Console.WriteLine("Done executing method2" );
    }
}

Then from the Python code (this is a rough guess based from the docs ): 然后从Python代码(这是一个基于文档的粗略猜测):

def f():
    print "Executing f"

# instantiate a delegate
f2 = testlib.MC.Callback(f)

# use it
mc.method2(f2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM