Calling Python from C++

In a previous post we already covered calling a C function from one Boost.Python module in another module.

What if instead we want to call a Python function directly from C? We’ll stick with the same Bird / Quacker metaphor as in the previous post, but we’ll now implement our duck class in PyDuck.py:

"""
PyDuck.py
"""

def quack():
    print "Python Quack"

Now how can we call Python from C++? It turns out that Boost.Python defines operator() for the object class, so calling Python is relatively easy.  But things become more difficult if we want to maintain a default implementation in C.

For example, one could imagine testing whether the Python object is set each time…

object quacker;

void callQuack() {
  if (quacker) {
    quacker();
  } else {
    default_quacker();
  }
}

But a cleaner approach is to instead use Boost.Function. This will allow all calls to use the same syntax as before, both when the quacker is set to a pure C function (i.e., default_quacker) or a callable Python object.

The final Bird.cpp file follows:

#include <boost/python.hpp>
#include <boost/function.hpp>
#include <iostream>

using namespace boost::python;

typedef void (quacker_t)(void);
boost::function<quacker_t> quacker;

void default_quacker() {
  std::cout << "No noise came out." << std::endl;
}

void setQuack(object obj) {
  quacker = obj;
}

void callQuack() {
  quacker();
}

BOOST_PYTHON_MODULE(Bird) {
  quacker = &default_quacker;

  def("setQuack", &setQuack);
  def("callQuack", &callQuack);
}

Testing it out:

>>> import Bird
>>> import PyDuck
>>>
>>> Bird.callQuack()
No noise came out.
>>>
>>> Bird.setQuack(PyDuck.quack)
>>> Bird.callQuack()
Python Quack

1 thought on “Calling Python from C++

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s