Skip to main content

Pybind11

Install

wget https://github.com/pybind/pybind11/archive/v2.9.1.tar.gz

Build

CMakeLists.txt
add_subdirectory (third_party/pybind11-2.9.1)

pybind11_add_module (lib_cpp lib.cpp)
target_link_libraries (lib_cpp PRIVATE pybind11::module)

Usage

Basics

lib.cpp
#include <pybind11/pybind11.h>

void my_func(const int input) {
}

class MyClass {
public:
MyClass() {
}
};

PYBIND11_MODULE(lib_cpp, m) {
namespace py = pybind11;
using namespace pybind11::literals;

m.def("my_func", &my_func, "input"_a);

py::class_<MyClass>(m, "MyClass")
.def(py::init<>());

}

Embed

project(test)
cmake_minimum_required(VERSION 3.10)

add_subdirectory(third_party/pybind11-2.9.1)

add_executable(lib_cpp lib.cpp)
target_link_libraries(lib_cpp PRIVATE pybind11::embed)
#include <pybind11/embed.h>
namespace py = pybind11;

int main() {
py::scoped_interpreter guard{};
auto plt = py::module_::import("matplotlib.pyplot");
auto np = py::module_::import("numpy");
py::list x = np.attr("linspace")(0, 10, 100);
py::list y = np.attr("sin")(x);
plt.attr("plot")(x, y);
plt.attr("grid")();
plt.attr("tight_layout")();
plt.attr("savefig")("plot.svg");
}

Output:

Or as OpenCV Mat:


#include "opencv2/opencv.hpp"

#include <pybind11/embed.h>

// [...]

figure.attr("canvas").attr("draw")();
auto buffer = figure.attr("canvas").attr("tostring_rgb")().cast<std::string>();
auto shape = figure.attr("canvas").attr("get_width_height")().cast<py::tuple>();
auto width = shape[0].cast<int>();
auto height = shape[1].cast<int>();

cv::Mat img(cv::Size{width, height}, CV_8UC3);
std::copy(buffer.data(), buffer.data() + width*height*3*sizeof(uint8_t), img.data);

cv::cvtColor(img, img, cv::COLOR_RGB2BGR);
cv::imshow("", img);
cv::waitKey(0);
find_package(OpenCV)

add_executable(lib_cpp lib.cpp)
target_link_libraries(lib_cpp
PRIVATE
pybind11::embed
opencv_core
opencv_imgproc
opencv_highgui)

Vector to python list

#include <pybind11/stl.h>

// [...]

auto x = py::cast(std::vector<double> {1,2, 3, 4, 5, 6, 7,8, 9, 10});
auto y = py::cast(std::vector<double> {1, -1, 3, 1, -3.3, 1, 2, 5,4,3});