[C++-sig] extending and callbacks in Boost.Python

kent at cognitoy.com kent at cognitoy.com
Fri Nov 14 23:16:36 CET 2003


Hi. I hope this question isn't too naive, but I've spent a couple of days
searching for the answer and haven't found it. I am trying to build an
application that extends Python with a collection of C++ libraries. In one
case, I want a library running an extended loop to call back into Python. 

I have set up something like this (sanitized for my protection):

A C++ base class:

---------
struct PythonCallback
{
	virtual int perFrameCallback() = 0;
};

struct PythonCallbackWrapper : PythonCallback
{
  PythonCallbackWrapper(PyObject* self_)
      : self(self_) {}
  int perFrameCallback() { return call_method<int>(self,
"perFrameCallback"); }
  PyObject* self;
};
---------

Then I have a callback registration function:

---------
PyObject* mPythonCallback;
void MyObject::setCallback(PyObject* p)
{
  mPythonCallback = p;
}
---------
And in my loop, I'm trying to do:

---------
  call_method<int>(mPythonCallback, "perFrameCallback"); 
---------

The import code is:

---------
BOOST_PYTHON_MODULE(MyObject)
{
  class_<MyObject>("MyObject")
    .def("doSomethingWithCallback", &MyObject::doSomethingWithCallback)
    .def("setCallback", &MyObject::setCallback)
  ;

  class_<PythonCallback, PythonCallbackWrapper,
boost::noncopyable>("PythonCallback")
  ;
}
---------

The python code looks like:

---------
import MyObject

class MyCallback(MyObject.PythonCallback):
  def perFrameCallback():
    return 42

m = MyObject.MyObject()
cb = MyCallback()
m.setCallback(cb)
m.doSomethingWithCallback()
---------

So that's the whole system. When I run it, the script loads and runs, and I
see that the setCallback method is receiving a PyObject*. But when I try to
call the callback through that pointer, it throws an exception:

  boost::python::error_already_set

My initial thought was that this must mean an error occurred earlier that I
had failed to handle, so I put a call to PyErr_Occurred() before this to
test that theory -- and it returned null (no outstanding errors).

At this point I'm stuck. I haven't found a way to figure out what's going
wrong. 

By the way, I've also tried a simpler approach of just placing a free
function in Python and passing in a reference to it in setCallback, and
then using the call function to call it. I get the same results.


Please, I'd appreciate some help here. It feels really close...but
something is going very wrong. I'd also greatly appreciate a pointer to
some document somewhere that talks about setting up callbacks from C++ into
Python where the Python code is running the outermost loop. And maybe a
pointer to an explanation of what I can do with a PyObject*. Although I've
read through every bit of documentation I can find, I feel as though I know
a lot of disconnected facts without having any good overarching view of the
system.

Thanks!

   Kent

---
   Kent Quirk
   CTO
   CogniToy


--------------------------------------------------------------------
mail2web - Check your email from the web at
http://mail2web.com/ .






More information about the Cplusplus-sig mailing list