in Tutorials, Windows

Embedding Python in C++

With this tutorial series we are going to explore the solutions to mix different programming languages, the options to communicate both languages and resolve the most common problems that we can find during their integration.

Introduction
Performance improvements

Our first experiment will be to mix Python and C++. We are going to initialize a python interpreter in a C++ application and import a python module to execute some function.

Instead of use CPython directly we are going to use the library pybind11 to facilitate the bindings and simplify the process.

cpp_python_app

Pybind11 is a header-only library so we just need to copy de include folder of the GitHub repository to our c++ project

pybind11_includes

We need to add this include folder to our c++ project/solution. Using Visual Studio we can find this option in Project > Properties > VC++ Directories > Include Directories. We need to add the pybind11 directory and the location of the Python.h file of the python that we will use for our python interpreter

vc_python_include

We can add now the folder to find the python library during the linkage phase. In Project > Properties > VC++ Directories > Library Directories

vc_python_libs

Now we can add the C++ code

#include <iostream>

#include <pybind11/embed.h>

namespace py = pybind11;
int main()
{
	{
		py::scoped_interpreter guard{};
		py::module_ math_module = py::module_::import("math");
		py::object result = math_module.attr("cos")(0.5);

		std::cout << "C++ cout" << std::endl;
		std::cout << py::cast<float>(result) << std::endl;

		py::print("Python print");
		py::print(result);
	}
	return 0;
}

In the first lines we are initializing the interpreter using a scoped guard. When we exit of the scope this interpreter will be destroyed. Every python object that is created in this scope must be released before the interpreter destruction, we can’t keep references to python objects outside their interpreter scope.

To import a module we can use pybind11::module_::import with the name of the module, this module is searched using the sys.path of the current interpreter. To access to the function we can use the module.attr with the name of the function and their function parameters after the call

To use the objects with c++ functions we need to cast their value to a compatible type, for our example we can cast the result python object from the math.cos function to a float to print the result.

Also we can use some builtin python functions directly with the python object, like print, to show the result value in the terminal

cpp_python_output

And that’s all, now we have a c++ application than can use python modules at runtime. A good way to be able to make changes without the need for recompilation the main app!

Support this blog!

For the past year I've been dedicating more of my time to the creation of tutorials, mainly about game development. If you think these posts have either helped or inspired you, please consider supporting this blog. Thank you so much for your contribution!

Write a Comment

Comment