[C++-sig] Problem with embedding python with boost.python

Pierre Barbier de Reuille pierre.barbier at cirad.fr
Mon Jul 7 11:07:58 CEST 2003


I try to embed python in a C++ program. I wrote a module that works if I 
compile it for extending python ... and I wrote a simple interpreter 
that works as an embedded one !

But now I want to extend the embedded interpreter to allow access to the 
C++ classes !

The extension module is called "editor". My problem is that whenever I 
try to import the module in python, the program just abort ... the 
import is done by evaluating 'import edtitor' inside the python 
interpreter ... I show you the interpreter code ! Of course, the module 
is defined using boost.python !

An extra-question is : if I use Py_file_input, I can't retrieve the 
output of the python command, if I use Py_single_input, I can retrieve 
the output, but I can't do any assignment or printing ... how can I have 
both ??? I really begin to think python was not designed to embedded :(

Tthe interpreter class is :

class PythonWnd : public QMainWindow
{
  Q_OBJECT

public:
  PythonWnd(QWidget * parent = 0, const char * name = 0, WFlags f = 
WType_TopLevel);
  ~PythonWnd();

public slots:
  void evalCommand();

protected:
  void LaunchPython();
  void ClosePython();
  void ExecutePython(const QString command);
  QTextEdit *output;
  QLineEdit *edit;
  QVBox *layout;
  boost::python::object main_module;
  boost::python::dict main_namespace;

};

The initialization function that is :

void PythonWnd::LaunchPython()
{
  // register the module editor with the interpreter
  if (PyImport_AppendInittab("editor", init_module_editor) == -1)
    {
      cerr << "Error, cannot load editor module !" << endl;
      throw std::runtime_error("Failed to add embedded_hello to the 
interpreter's "
                   "builtin modules");
    }
  // Initialize the interpreter
  Py_Initialize();
  // Get the main module ...
  main_module = 
object(boost::python::handle<>(borrowed(PyImport_AddModule("__main__"))));
  main_namespace = 
dict(boost::python::handle<>(borrowed(PyModule_GetDict(main_module.ptr()))));
}

Then the interpretor function (launched each time a line is to be 
evaluated ... it's an iteractive interpretor) is:

void PythonWnd::ExecutePython(const QString command)
{
  char *cmd;
  cmd = new char[command.length()+1];
  strcpy(cmd, command.latin1());
  stringstream ss;
  try
    {
      PyObject *obj = PyRun_String(cmd, Py_file_input, 
main_namespace.ptr(), main_namespace.ptr());
      boost::python::handle<> hres(obj);
      boost::python::object res(hres);
      //std::string res_cmd = extract<std::string>(res.attr("__repr__")());
      std::string res_cmd = call_method<std::string>(res.ptr(),"__repr__");
      ss << res_cmd;
    }
  catch(error_already_set)
    {
      PyErr_Print();
      ss << "Error, exception thrown ... look at console for details" << 
endl;
      PyObject *exception, *v, *tb, *hook;
    }
  output->append(ss.str().c_str());
  delete cmd;
}


-- 
Pierre Barbier de Reuille

INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP
Botanique et Bio-informatique de l'Architecture des Plantes
TA40/PSII, Boulevard de la Lironde
34398 MONTPELLIER CEDEX 5, France

tel   : (33) 4 67 61 65 77    fax   : (33) 4 67 61 56 68 






More information about the Cplusplus-sig mailing list