[IronPython] Embedding IronPython and calling python functions from C#

Dino Viehland dinov at microsoft.com
Tue Jun 16 01:36:17 CEST 2009


What about the code which is actually running the code that "def OnConnect" lives in?

I would expect you have either:
        engine.ExecuteFile(..., scope)

or:


code = engine.CreateScriptSource*(...)
cc = code.Compile()
cc.Execute(scope)

or

code = engine.CreateScriptSource*(...)
code.Execute(scope)

where scope in all of these would be the scope that you've populated with the value of "x".

I suspect the 2nd one is the one you want so that you can run the same code against multiple
scopes w/ different sets of bound variables based upon the current request.


-----Original Message-----
From: users-bounces at lists.ironpython.com [mailto:users-bounces at lists.ironpython.com] On Behalf Of Patrick van der Willik
Sent: Monday, June 15, 2009 4:26 PM
To: Discussion of IronPython
Subject: Re: [IronPython] Embedding IronPython and calling python functions from C#

The actual code that uses these variables from within a script looks
like this:
def OnConnect(user):
    s = "The value of x: " + str(x)
    user.Send(s, True)
    user.Receiver = "user_username"
    return True

And the complete exception is:
[ERROR] [16-6-2009 1:18:16] An error occured while attempting to accept
a new connection. Error: name 'x' is not defined
[ERROR] [16-6-2009 1:18:16] Stacktrace:    at
IronPython.Runtime.PythonContext.MissingName(SymbolId name)
   at Microsoft.Scripting.Runtime.ModuleGlobalWrapper.GetCachedValue()
   at Microsoft.Scripting.Runtime.ModuleGlobalWrapper.get_CurrentValue()
   at S$2.OnConnect$6(Object user)
   at _stub_$17##8(Closure , CallSite , Object , User )
   at Microsoft.Scripting.Actions.MatchCaller.Call2[T0,T1,TRet](Func`4
target, CallSite site, Object[] args)
   at Microsoft.Scripting.Actions.CallSite`1.UpdateAndExecute(Object[] args)
   at
Microsoft.Scripting.Actions.UpdateDelegates.Update2[T,T0,T1,TRet](CallSite
site, T0 arg0, T1 arg1)
   at System.Boolean(User)(Object[] , User )
   at TestProject.Users.ConnectionManager.AcceptNewConnnections() in
C:\Users\Patrick\Documents\Visual Studio
2008\Projects\test\TestProject\Users\ConnectionManager.cs
:line 108

Weird thing is: If I use GetVariable, it works fine. The call is done at
a later location in the program that where I do the SetVariable, but the
script scope hasn't ben changed in the meantime.

Patrick

Michael Foord wrote:
> Patrick van der Willik wrote:
>> Alright, that actually really worked pretty good, and I finally got
>> it all working as it should. However, I'm running into 1 more little
>> issue, now I need to go the other way around aswell. I have several
>> functions marked in my application as PythonExportable. In a certain
>> startup phase of the application, after creating the IronPython
>> hosting environment, I walk over all these classes using Reflection,
>> take the tagged functions and put these into my IP scope.
>>
>> However, my simple tests for some reason cause my SetVariable() calls
>> to not work. I added 2 tests to my scripts, one where I add a
>> variable into the scope and another one where I add a delegate.
>> However, in both cases, whenever I use these variables from within my
>> scripts, they don't seem to work. Code:
>>                Func<string> test = new Func<string>(Test);
>>                scope.SetVariable("x", 10);
>>                scope.SetVariable("Test", test);
>>
>> Accessing them in my scripts have the effect of triggering an
>> exception that shows that x is undefined.
>
> Can you show the actual code that attempts to use them and the actual
> exception message raised.
>
> Michael
>
>>
>> Some insights into this would be of great help.
>>
>> Patrick
>>
>> Michael Foord wrote:
>>> See this section of my hosting article:
>>>
>>> http://www.voidspace.org.uk/ironpython/hosting_api.shtml#functions-as-delegates
>>>
>>>
>>> You cast the function to a delegate as you fetch it out of the scope.
>>>
>>> Michael
>>>
>>> Patrick van der Willik wrote:
>>>> I'm a bit late with responding to this as I was kinda busy. I used
>>>> the code that was given Stephen and it seems to run properly
>>>> without throwing exceptions. However, I created a little
>>>> autoexec.py file with a simple function in it with 2 parameters.
>>>>
>>>> The main problem here is: How do I call the function through the
>>>> scope? I used engine.CreateScope() to create myself a new scope,
>>>> but from there on, I'm basically lost(again). What I basically want
>>>> to do, is call my function 'add' with 2 parameters(say, 10 and 15).
>>>> The modules itself are loaded into a ScriptSource.
>>>>
>>>> Thanks,
>>>> Patrick
>>>>
>>>> Lepisto, Stephen P wrote:
>>>>>
>>>>> What I do when I want to work with python modules from embedded
>>>>> IronPython is set the IronPython search path with the path of the
>>>>> module to load then  create and execute a small python script that
>>>>> loads the main python modules into the current scope.
>>>>>
>>>>>
>>>>>
>>>>> string moduleName = Path.GetFileName(modulePath);
>>>>>
>>>>> string path = Path.GetDirectoryName(modulePath);
>>>>>
>>>>>
>>>>>
>>>>> ICollection<string> paths = _pythonEngine.GetSearchPaths();
>>>>>
>>>>> if (!paths.Contains(path))
>>>>>
>>>>> {
>>>>>
>>>>>     paths.Add(path);
>>>>>
>>>>>     _pythonEngine.SetSearchPaths(paths);
>>>>>
>>>>> }
>>>>>
>>>>> string modInvoke = String.Format("import {0}\nfrom {0} import
>>>>> *\n", moduleName);
>>>>>
>>>>> ScriptSource source =
>>>>> _pythonEngine.CreateScriptSourceFromString(modInvoke,
>>>>>
>>>>>
>>>>> Microsoft.Scripting.SourceCodeKind.Statements);
>>>>>
>>>>>
>>>>>
>>>>> Where modulePath is the full path to the python module or package
>>>>> to load.
>>>>>
>>>>>
>>>>>
>>>>> I can then invoke methods or access attributes using the
>>>>> IronPython scope.  In this way, I can interact with the python
>>>>> modules for as long as necessary before closing down the
>>>>> scope/engine.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> *From:* users-bounces at lists.ironpython.com
>>>>> [mailto:users-bounces at lists.ironpython.com] *On Behalf Of *Dody
>>>>> Gunawinata
>>>>> *Sent:* Thursday, June 11, 2009 9:09 AM
>>>>> *To:* Discussion of IronPython
>>>>> *Subject:* Re: [IronPython] Embedding IronPython and calling
>>>>> python functions from C#
>>>>>
>>>>>
>>>>>
>>>>> You can read all yours file scripts, then using StringBuilder to
>>>>> combine then and call CreateScriptSourceFromString()
>>>>>
>>>>> Then you can call your functions within the combined scripts
>>>>> normally. Pretty much you are creating a giant source code on the
>>>>> fly.
>>>>>
>>>>>
>>>>>
>>>>> On Thu, Jun 11, 2009 at 5:32 PM, Patrick van der Willik
>>>>> <patrick at toolmaker.nl <mailto:patrick at toolmaker.nl>> wrote:
>>>>>
>>>>> I'm currently attempting to embed the IronPython 2 runtimes into
>>>>> an existing application written in C#. However, I find the amount
>>>>> of documentation lacking on what I'm trying to do. I currently
>>>>> have a proof-of-concept version which uses Lua and LuaInterface,
>>>>> but the people who have to write the scripts dislike Lua(Well,
>>>>> more hate it with a passion) and would love to see this working
>>>>> with Python.
>>>>>
>>>>> My host application is a networked application that must trigger
>>>>> certain scripts functions on events generated by the connected
>>>>> clients. The idea is that when my application starts, it will load
>>>>> the IronPython script environment, launches an 'autoexec.py' which
>>>>> will load various other scripts files and do some housekeeping.
>>>>> Once this all is completed, it will start listening to incoming
>>>>> connections. However, in various scenarios, the application has to
>>>>> trigger scripted functions when data is received from a client.
>>>>> Which script function is called is different per client and per
>>>>> event. I have events for connecting, logging on, disconnecting and
>>>>> a set of data specific events after receiving data. This highly
>>>>> depends on the received packets.
>>>>>
>>>>> My question here is: How do I embed IronPython in such a fashion
>>>>> that I can load my scripts and then trigger various functions
>>>>> within that? I've seen many examples that just call
>>>>> CreateScriptSourceFromString() or File each time in which just 1
>>>>> piece of code is implemented. This is not suitable for the needs
>>>>> here because the scripted systems can become quite complex.
>>>>>
>>>>> With regards,
>>>>> Patrick
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Users mailing list
>>>>> Users at lists.ironpython.com <mailto:Users at lists.ironpython.com>
>>>>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> nomadlife.org <http://nomadlife.org>
>>>>>
>>>>> ------------------------------------------------------------------------
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Users mailing list
>>>>> Users at lists.ironpython.com
>>>>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>>>>
>>>>
>>>> ------------------------------------------------------------------------
>>>>
>>>>
>>>> _______________________________________________
>>>> Users mailing list
>>>> Users at lists.ironpython.com
>>>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>>>>
>>>
>>>
>>
>> _______________________________________________
>> Users mailing list
>> Users at lists.ironpython.com
>> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>
>

_______________________________________________
Users mailing list
Users at lists.ironpython.com
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com



More information about the Ironpython-users mailing list