This example shows how to create a C++ program that runs a Python script that has access to variables and functions defined in the C++ program itself.
The first step is to include the pybind11
's embed.h
library:
#include <pybind11/embed.h>
We then need to load the Python interpreter:
py::scoped_interpreter guard{};
We do not directly use it and it will be automatically destroyed when it goes out of scope.
In the local environment variable, we create a variable and a function that will be injected in the the Python script's environment:
auto local = py::dict();
local["y"] = ...;
local["set_the_answer"] = ...;
The scope
variable contains the scope of the main module of our interpreter:
py::object scope = py::module::import("__main__").attr("__dict__");
We can finally evaluate our Python script:
py::eval_file("set-the-y.py", scope, local);
What does the script do?
set_the_answer(y - 1)
It simply calls the set_the_answer()
function we have defined by passing the injected variable y
decremented by one.
The final effect is that the val_out
variable we have defined in our C++ code will now have a value of 42 (y - 1
) instead of the original 7
.
You can try it with:
$ mkdir build
$ cd build
$ cmake
$ make
$ ./scripting
With the configure_file
command, CMakeLists.txt
copies the Python script into the build directory.
You can modify the Python Script in your build directory and see that the value printed by the scripting
program will change accordingly.
- What does it mean that we cannot have two concurrent interpreters (as mentioned in the pybind11 documentation)?