5

我正在尝试使用 python 中的 C# 类,在单声道/ubuntu 上使用 python.net。

到目前为止,我设法用一个参数工作进行了一个简单的函数调用。我现在要做的是将 python 回调传递给 C# 函数调用。

我在下面尝试了以下变体,但都没有奏效。有人可以展示如何使其工作吗?

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

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)              
4

2 回答 2

5

尝试传递ActionorFunc而不是原始函数:

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

蟒蛇代码:

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))

这是控制台输出:

Hello
Executing method1
42.0
Executing method2
exec f
Done executing method2

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;

        }
    }
}

我再次阅读了 Python.net Using Generics的文档,还发现这个Python.NET Naming and resolution of generic types看起来你需要显式指定参数类型

从那里引用

(反映的)泛型类型定义(如果存在具有给定基本名称的泛型类型定义,并且不存在具有该名称的非泛型类型)。这个泛型类型定义可以使用 [] 语法绑定到一个封闭的泛型类型中。尝试使用 () 实例化泛型类型 def 会引发 TypeError。

于 2014-03-20T23:35:06.587 回答
2

看起来您应该明确定义您的委托:

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" );
    }
}

然后从 Python 代码(这是基于docs的粗略猜测):

def f():
    print "Executing f"

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

# use it
mc.method2(f2)
于 2014-03-15T23:13:41.220 回答