Compiling python functions on the fly & calling from C++

Borse, Ganesh ganesh.borse at credit-suisse.com
Tue Nov 20 23:26:25 EST 2007


I want to call Python function which takes input arguments (parameters) from C++ program on the fly when program is running, as below:

def isSizeSmall(size,vol,ADV,prod):
    if ( (size < 1000) & (vol < (0.001 * ADV)) & (prod=="Stock")): return 100
    else: return 11

I tried following approaches for this but none worked.
1)Using PyEval_CallObject:- (After reading http://docs.python.org/ext/callingPython.html)
   But for getting a ptr to Python function using PyObject_GetAttrString, a module has to be imported.
   I cannot do so because I am generating the Python function source code at run time & so cannot create module of it.
   So, I could not use this approach.

2)Using Py_CompileString & then using PyEval_EvalCode function:-
   For this I passed above function source code to Py_CompileString, which compiled fine.
   Then I packed the values for these parameters in Dictionary object, as below & passed that as 2nd input parameter to PyEval_EvalCode.


   This function call also passed, but did not given any output.

Can someone please help me know following?
A) How can I compile a Python function at runtime (not by loading module from file) & then call it many times in the same program?
B) How to make sense out of the PyObject* returned by the PyEval_EvalCode function?

Thanks in advance for the help.

Warm Regards,
Ganesh

------------------
   PyObject *glb, *loc;  
   glb = PyDict_New();
   PyDict_SetItemString(glb, "__builtins__", PyEval_GetBuiltins());
   loc = PyDict_New();
   PyObject* val = 0;
   
   val = PyInt_FromLong(ordval.size);
   PyDict_SetItemString(loc,"size",val);
   
   val = PyInt_FromLong(ordval.vol);
   PyDict_SetItemString(loc,"vol",val);
   
   val = PyInt_FromLong(ordval.ADV);
   PyDict_SetItemString(loc,"ADV",val);
   
   val = PyString_FromString(ordval.prod);
   PyDict_SetItemString(loc,"prod",val);

/*** with stdin & Py_file_input ***/
   PyObject* result = NULL;
   result = Py_CompileString(szExpr,"<stdin>", Py_file_input);
   if(result!=NULL){
     printf("str compiled fine with stdin & Py_file_input, calling PyEval_EvalCode\n");
     PyCodeObject *pyCo = (PyCodeObject *)result;
     PyObject* evalret = NULL;
     evalret = PyEval_EvalCode(pyCo,glb,loc);
     if(!evalret || PyErr_Occurred())
       PyErr_Print();
     else
       printf("ok [%d] size [%d]\n",PyObject_Print(evalret,stdout,0),PyObject_Size(evalret));
------------------
Output shows as below:
Expression to eval = 
[def isSizeSmall(size,vol,ADV,prod):
  if ( (size < 1000) & (vol < (0.001 * ADV)) & (prod=="Stock")): print "OK"; return 10
  else: print "NOK"; return 11


]
str compiled fine with stdin & Py_file_input, calling PyEval_EvalCode
Noneok [0] size [-1]
------------------

==============================================================================
Please access the attached hyperlink for an important electronic communications disclaimer: 

http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html
==============================================================================




More information about the Python-list mailing list