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.
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.