×

Discussion Board

Results 1 to 8 of 8
  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    6

    Minimal code to run script in application

    Hello,

    I am trying to run python scripts from standard C++ application.
    I have checked the code of the python application done by Nokia and tried to use the same "CSPyInterpreter" object but i always receive a KErrGeneral (-2) error!

    Is there a minimal code available to run pyhton scripts from application?
    Is there some "evident" requirements to follow?

    Some others related question:
    Is there a mean to give arguments to the python scripts?
    Is it possible to exchange data between the python script and the application in both ways?

    Squal.

  2. #2
    Registered User
    Join Date
    Oct 2007
    Posts
    6

    Re: Minimal code to run script in application

    I have found some code here:

    http://wiki.forum.nokia.com/index.ph...ymbian_C%2B%2B

    but unfortunately some variables are not defined...
    -> pre_handler
    -> aString

    and i have not for the moment found explanatino about those methods PyDict_GetItemString and Py_BuildValue.

  3. #3
    Regular Contributor
    Join Date
    Oct 2007
    Posts
    67

    Re: Minimal code to run script in application

    Quote Originally Posted by Squal View Post
    .. and i have not for the moment found explanation about those methods PyDict_GetItemString and Py_BuildValue.
    See Python C-API documentation

  4. #4
    Regular Contributor
    Join Date
    Apr 2007
    Location
    Lublin, Poland
    Posts
    81

    Re: Minimal code to run script in application

    First of all, here:

    http://docs.python.org/ext/ext.html
    http://docs.python.org/api/api.html

    ... you'll find most documentation including those functions you mentioned. Python/C in PyS60 uses essentialy the same API. Minor differences are more or less explained in 9th chapter of PyS60 docs.

    Like you say, wiki example is flawed. I'll post mine, slightly corrected version:
    Code:
    #include <Python.h>
    #include <CSPyInterpreter.h>
    #include "Embedder.h"
    
    void Embedder::Execute(const TDesC& aMethod, TDes& aOutput)
    	{
    	TInt retVal(KErrNone);
    	 
    	// Create a  Python interpreter
    	CSPyInterpreter* it = CSPyInterpreter::NewInterpreterL();
    	CleanupStack::PushL(it);
    	
    	// Save state of any current Python interpreter, and acquire the interpreter lock
    	PyEval_RestoreThread(PYTHON_TLS->thread_state);
    	
    	char *module_name = "Embedded" ;
    	const char *method = "eggsMaybe" ;
    	char *response = "" ;
    	
    	TInt32 r_len = 0 ;
    	PyObject *pModule = PyImport_ImportModule(module_name) ;
    	if ( pModule != NULL )
    		{
    		PyObject *module_dict = PyModule_GetDict(pModule) ;
    		PyObject *expression = PyDict_GetItemString(module_dict, method) ;
    		PyObject *arglist = NULL;
    		PyObject *result = PyEval_CallObject(expression, arglist);
    		response = PyString_AsString( result ) ;
    		r_len = strlen( response ) ;
    		}
    	
    	// Make a Symbian descriptor pointer to the char * response
    	TPtrC8 symResponse((TUint8*)response, r_len ) ;
    	aOutput.Copy(symResponse);
    	
    	// Clean-up, and restore thread state
    	PyEval_SaveThread();
    	CleanupStack::PopAndDestroy(it);
    	}
    I'll also post an example of calling a script with arguments. It may be needlessly complicated, it's been a while, but I recall I had some difficulties with correct descriptors' format.
    Code:
    #include <Python.h>
    #include <CSPyInterpreter.h>
    #include <f32file.h>
    #include "SMS.h"
    
    void SMS::SendSMSL(const TDesC& aNumber, const TDesC& aMessage)
    	{
    	// Run python send sms code with arguments provided.
    	CSPyInterpreter* it = CSPyInterpreter::NewInterpreterL();
    	CleanupStack::PushL(it);
    
    	// Run a script file with args.
    	// ... Get a path to the script.
    	_LIT(KScriptFile, "SendSMS.py");
    	const TInt KMaxPathLength = 128;
    	TBuf<KMaxPathLength> scriptPath;
    	RFs fs;
    	User::LeaveIfError(fs.Connect());
    	CleanupClosePushL(fs);
    	User::LeaveIfError(fs.CreatePrivatePath(EDriveC));
    	User::LeaveIfError(fs.PrivatePath(scriptPath));
    	scriptPath.Append(KScriptFile);
    	CleanupStack::PopAndDestroy(&fs);
    	
    	// ... Prepare all args to 8b pointers.
    	const TInt KForZeroTerminate = 1;
    	HBufC8* scriptPath8bBuf = HBufC8::NewLC(scriptPath.Length() + KForZeroTerminate);
    	TPtr8 scriptPath8b = scriptPath8bBuf->Des();
    	scriptPath8b.Copy(scriptPath);
    	char* scriptPathPtr = (char*)scriptPath8b.PtrZ();
    	
    	HBufC8* number8bBuf = HBufC8::NewLC(aNumber.Length() + KForZeroTerminate);
    	TPtr8 number8b = number8bBuf->Des();
    	number8b.Copy(aNumber);
    	char* numberPtr = (char*)number8b.PtrZ();
    	
    	HBufC8* message8bBuf = HBufC8::NewLC(aMessage.Length() + KForZeroTerminate);
    	TPtr8 message8b = message8bBuf->Des();
    	message8b.Copy(aMessage);
    	char* messagePtr = (char*)message8b.PtrZ();
    
    	// ... Run the script.
    	char* argv[3] = { scriptPathPtr, numberPtr, messagePtr };
    	TInt pyError = it->RunScript(sizeof(argv) / sizeof(*argv) /* just for fun */, argv);
    	User::LeaveIfError(pyError);
    	
    	// ... Cleanup a bit.
    	CleanupStack::PopAndDestroy(message8bBuf);
    	CleanupStack::PopAndDestroy(number8bBuf);
    	CleanupStack::PopAndDestroy(scriptPath8bBuf);
    	
    	CleanupStack::PopAndDestroy(it);
    	}
    If the code won't work for you, let me know, cause I've only assumed it's in the working condition;>
    whatever happens happens

  5. #5
    Registered User
    Join Date
    Oct 2007
    Posts
    6

    Re: Minimal code to run script in application

    Hello,

    Thank you very much for your reply and for your example.

    I have still one question.
    The code "PyObject *pModule = PyImport_ImportModule(module_name)" always return a null pointer so the module is not found.

    For me a module is a python script. Is it right?
    I have checked Py_GetPath and this function returns c:\resource but even if my script is in c:\resource the pointer is null.

    Do i must apply something more? Must the script include something special?

    I have read documentation but for the moment i don't see an "evident" response.

  6. #6
    Regular Contributor
    Join Date
    Apr 2007
    Location
    Lublin, Poland
    Posts
    81

    Re: Minimal code to run script in application

    I've tested the first example now, all's well.
    My 'Embedded.py' script:
    Code:
    def eggsMaybe():
        return 'eggs from embedded world'
    indeed resides in the c:\resource dir on emulator. Other than that, I don't know what may be wrong.
    I'm still working on PyS60_1.4.0 but I don't think that matters.
    whatever happens happens

  7. #7
    Registered User
    Join Date
    Oct 2007
    Posts
    6

    Re: Minimal code to run script in application

    Hello,

    With a simple script as your example, it's working!!

    Something in my script puzzles the "import" phase...i will try to invesigate why.

    Thank you very much
    Squal.

  8. #8
    Registered User
    Join Date
    Oct 2007
    Posts
    6

    Re: Minimal code to run script in application

    Hello,

    I have found the guilty!
    I had "import appuifw" in my script. I used it before to allow user input...

    Now the issue is definitely closed!

Similar Threads

  1. Replies: 3
    Last Post: 2007-09-26, 15:41
  2. Replies: 13
    Last Post: 2007-09-12, 13:45
  3. problems to run simple java application
    By Kaysc in forum Mobile Java General
    Replies: 3
    Last Post: 2005-10-04, 01:39
  4. How to run my application in J-Sky emulator
    By bb_sathya in forum Mobile Java Tools & SDKs
    Replies: 0
    Last Post: 2005-09-01, 08:12
  5. N9200 (Perl) Application Wizard generates buggy code?
    By bitnir in forum Symbian Tools & SDKs
    Replies: 0
    Last Post: 2004-04-14, 04:33

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×