call a Python function from c++ using pybind11

stanleyli picture stanleyli · Mar 1, 2017 · Viewed 7.2k times · Source

I am trying to call a python function from a C++ code which contains main() function using Pybind11. But I found very few references are available. Most of existing documents talk about the reversed direction, i.e. calling C++ from Python.

Is there any complete example showing how to do that? The only reference I found is: https://github.com/pybind/pybind11/issues/30

But it has very little information.

Answer

Jason Rhinelander picture Jason Rhinelander · Jul 14, 2017

The answer to your question really has two parts: one about calling a Python function from C++, the other about embedding the interpreter.

Calling a function in pybind11 is simply a matter of getting that function into a pybind11::object variable, on which you can invoke operator() to attempt to call the object. (It doesn't have to be a function, but just something callable: for example, it could also be an object with a __call__ method). For example, to call math.sqrt(2) from C++ code you'd use:

auto math = py::module::import("math");
auto resultobj = math.attr("sqrt")(2);
double result = resultobj.cast<double>();

or you could condense it all to just:

double result = py::module::import("math").attr("sqrt")(2).cast<double>();

The second part of the question involves how to do this from a C++ executable. When building an executable (i.e. when your C++ code contains main()) you have to embed the Python interpreter in your binary before you can do anything with Python (like calling a Python function).

Embedded support is a new feature added in the current pybind11 master branch (which will become the 2.2 release). Here's a basic example that starts an embedded Python interpreter and calls a Python function (math.sqrt):

#include <pybind11/embed.h>
#include <iostream>

namespace py = pybind11;

int main() {
    py::scoped_interpreter python;

    auto math = py::module::import("math");
    double root_two = math.attr("sqrt")(2.0).cast<double>();

    std::cout << "The square root of 2 is: " << root_two << "\n";
}

Outputs:

The square root of 2 is: 1.41421

More examples and documentation of calling functions and embedding are available at http://pybind11.readthedocs.io/en/master/advanced/pycpp/object.html and http://pybind11.readthedocs.io/en/master/advanced/embedding.html, respectively.