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

Patrick van der Willik patrick at toolmaker.nl
Tue Jun 16 01:48:40 CEST 2009


I am in fact using the 2nd 'flavour':
                string modInvoke = String.Format("import {0}\nfrom {0} 
import *\n", "autoexec");
               
                var source = 
engine.CreateScriptSourceFromString(modInvoke, SourceCodeKind.Statements);
                CompiledCode cc = source.Compile();
                cc.Execute(scope);

                // And bind our public delegates
                OnConnect = scope.GetVariable<Func<User, 
bool>>("OnConnect");
                OnDisconnect = scope.GetVariable<Func<User, 
bool>>("OnDisconnect");
                OnDataRecv = scope.GetVariable<Func<User, string, 
bool>>("OnDataReceived");
                OnPreLogin = scope.GetVariable<Func<User, 
bool>>("OnPreLogin");
                OnLogin = scope.GetVariable<Func<User, bool>>("OnLogin");

                Func<string> test = new Func<string>(Test);
                scope.SetVariable("x", 10);
                scope.SetVariable("Test", test);

And in a later piece of code, I just call the OnConnect(newUser) 
delegate(in my C# part). Perhaps interesting to know, the autoexec has 
an import clientconn and from clientconn import *.

Is my assumption that should work correct or am I missing something?

Patrick

Dino Viehland wrote:
> 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
> _______________________________________________
> Users mailing list
> Users at lists.ironpython.com
> http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>
>   

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20090616/c5df1557/attachment.html>


More information about the Ironpython-users mailing list