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