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++”