0

This is kind of follow up questions of Integration of C#, F#, IronPython and IronRuby

In order to use C/C++ function from Python, SWIG is the easiest solution. The reverse way is also possible with Python C API, for example, if we have a python function as follows

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

We can come up with the wrapper in C to use this python as follows.

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

How about the IronPython/C# or even F#?

  • How to call the C#/F# function from IronPython? Or, is there any SWIG equivalent tool in IronPython/C#?
  • How to call the IronPython function from C#/F#? I guess I could use "engine.CreateScriptSourceFromString" or similar, but I need to find a way to call IronPython function look like a C#/F# function, not writing the code in a string, but reading from a file.
Community
  • 1
  • 1
prosseek
  • 182,215
  • 215
  • 566
  • 871
  • What is the question? What is not answered by the question you linked? – Brian Jun 14 '10 at 16:20
  • See also e.g. http://blogs.msdn.com/b/nickhodge/archive/2008/11/12/ironpython-f-parallel-async-a-kittehz-brekfst.aspx – Brian Jun 14 '10 at 16:22

4 Answers4

5

You say 'now writing the code in a string, but reading from a file', so ok, read the file.

Python from F#:

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

F# from Python:

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

I just got these from the links in this question. Have not tried it, but, like, it's straightforward, I think it 'just works'. Dunno what else you are asking for.

Brian
  • 117,631
  • 17
  • 236
  • 300
3

Maybe this can help: F# and Iron Python?

desco
  • 16,642
  • 1
  • 45
  • 56
2

I read some of the answers from your previous question. One article that Kevin linked answers your question. It was on Ruby, so maybe you didn't read it. I don't know much about the DLR, but I think its purpose is to make access uniform, so the same code should work with Python.

Anyway, http://www.highoncoding.com/Articles/573_First_Look_at_the_IronRuby.aspx gives a .NET 4.0 example in C# that uses dynamic to make interop super-easy. Mirroring the C example you gave, and following on from Brian's code,:

//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();

This is based on the Ruby code:

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

I imagine that the equivalent Python can be accessed in exactly the same way. I didn't know you could do this with the DLR until I read the article that was linked from your previous question. It's pretty exciting that interop is so easy in C#. (Though I wouldn't really want dynamic in F# because F# code gives off a much more static feel.)

Nathan Shively-Sanders
  • 18,329
  • 4
  • 46
  • 56
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);
Milind Morey
  • 2,100
  • 19
  • 15