如何从C#/ F#调用IronPython函数?

时间:2010-06-14 15:59:53

标签: c# f# ironpython

这是Integration of C#, F#, IronPython and IronRuby

的后续问题

为了使用Python的C / C ++功能,SWIG是最简单的解决方案。 使用Python C API也可以采用相反的方法,例如,如果我们有一个python函数,如下所示

def add(x,y):
    return (x + 10*y)

我们可以在C中提出使用此python的包装器,如下所示。

double Add(double a, double b)
{
    PyObject *X, *Y, *pValue, *pArgs;
    double res;

    pArgs = PyTuple_New(2);
    X = Py_BuildValue("d", a);
    Y = Py_BuildValue("d", b);

    PyTuple_SetItem(pArgs, 0, X);
    PyTuple_SetItem(pArgs, 1, Y);
    pValue = PyEval_CallObject(pFunc, pArgs);
    res = PyFloat_AsDouble(pValue);    

    Py_DECREF(X);
    Py_DECREF(Y);
    Py_DECREF(pArgs);
    return res;
}

IronPython / C#甚至F#怎么样?

  • 如何从IronPython调用C#/ F#函数?或者,IronPython / C#中是否有任何SWIG等效工具?
  • 如何从C#/ F#调用IronPython函数?我想我可以使用“engine.CreateScriptSourceFromString”或类似的东西,但我需要找到一种方法来调用IronPython函数看起来像一个C#/ F#函数,不是在字符串中编写代码,而是从文件中读取。

4 个答案:

答案 0 :(得分:5)

你说'现在用字符串写代码,但是从文件中读取',好的,读取文件。

来自F#的Python:

let s = File.ReadAllLines("foo.py")
let engine = Python.CreateEngine()
let scriptSource = 
    engine.CreateScriptSourceFromString(s, SourceCodeKind.Statements)
...

来自Python的F#:

import clr   
clr.AddReferenceToFile("SomeFsLib.dll") 

我刚从这个问题的链接中得到了这些。没有尝试过,但是,它很简单,我觉得它“有效”。不知道你还想要什么。

答案 1 :(得分:3)

也许这有助于: F# and Iron Python

答案 2 :(得分:2)

我从您之前的问题中读到了一些答案。凯文链接的一篇文章回答了你的问题。这是在Ruby上,所以也许你没有阅读它。我对DLR知之甚少,但我认为其目的是使访问统一,因此相同的代码应该与Python一起使用。

无论如何,http://www.highoncoding.com/Articles/573_First_Look_at_the_IronRuby.aspx在C#中给出了一个.NET 4.0示例,该示例使用dynamic来使interop超级简单。镜像你给出的C示例,然后继续使用Brian的代码:

//Brian's code goes here, but C#-ified with `var` instead of `let`
engine.Execute();
object personClass = engine.Runtime.Globals.GetVariable("Person");
dynamic person = engine.Operations.CreateInstance(personClass);
person.greet();

这是基于Ruby代码:

class Person
  def greet()
    puts 'hello world'
  end
end

我认为可以以完全相同的方式访问等效的Python。我不知道你能用DLR做到这一点,直到我读到你上一个问题中链接的文章。令人兴奋的是,C#中的互操作非常简单。 (虽然我不想在F#中使用dynamic,因为F#代码会给出更加静态的感觉。)

答案 3 :(得分:1)

    pyEngine = Python.CreateEngine();
                    pyScope = pyEngine.CreateScope();
                    var instance = pyEngine.Execute(@" 
                    def test(a,b): 
                    return a+b 
                    ", pyScope);

                    var test = pyScope.GetVariable<Func<int,int, int>>("test");
                    int s = test(2,3);
                    MessageBox.Show( Convert.ToString( test));
                    var ops = pyEngine.CreateOperations(pyScope);