SlideShare a Scribd company logo
MIXING C++ & PYTHON II:
PYBIND11
IGOR SADCHENKO
IGOR.SADCHENKO@GMAIL.COM
ABOUT PYTHON
2
Python is a high-level general purpose programming language that focuses
on developer productivity improving and code readability.
The syntax of the core Python is minimalistic. At the same time, the
standard library includes a large amount of useful functions.
Python supports multiple programming paradigms, including structured,
object-oriented, functional, imperative, and aspect-oriented.
The main architectural features – dynamic typing, automatic memory
management, full introspection, handling mechanism exception, multi-
threaded computing and comfortable high-level data structure support.
The disadvantages include low performance and the lack of real multi-
threading (GIL)
C++ COREHARD AUTUMN 2017 //
IGOR SADCHENKO // C++ COREHARD // 14.10.17
PYTHON
3
C++ COREHARD AUTUMN 2017
4
C++ COREHARD AUTUMN 2017 //
IGOR SADCHENKO // C++ COREHARD // 14.10.17
C++ & PYTHON
Python and C++ easily complement each other.
Python gives you rapid development and flexibility
C++ gives you speed and industrial strength tools.
5
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
INTRO
7
pybind11 is a lightweight header-only library that exposes C++ types in
Python and vice versa, mainly to create Python bindings of existing C++
code.
Think of this library as a tiny self-contained version of Boost.Python with
everything stripped away that isn’t relevant for binding generation.
Without comments, the core header files only require ~4K lines of code and
depend on Python (2.7 or 3.x, or PyPy2.7 >= 5.7) and the C++ standard
library. This compact implementation was possible thanks to some of the
new C++11 language features (specifically: tuples, lambda functions and
variadic templates).
Since its creation, this library has grown beyond Boost.Python in many ways,
leading to dramatically simpler binding code in many common situations.
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
PYBIND11
8
Boost.Python
pybind11
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
PYBIND11
9
Python 2.7, 3.x, and PyPy (PyPy2.7 >= 5.7) are supported with an implementation-
agnostic interface.
It is possible to bind C++11 lambda functions with captured variables.
Using move constructors/assignment whenever possible to efficiently transfer
custom data types.
It's easy to expose the internal storage of custom data types through Pythons' buffer
protocols.
Automatic vectorization of functions for NumPy array arguments.
Python's slice-based access and assignment operations can be supported with just a
few lines of code.
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
ADVANTAGES
10
Everything is contained in just a few header files.
Binaries and compile time are generally smaller by factor 2 vs. to equivalent
bindings of Boost.Python.
Function signatures are precomputed at compile time (using constexpr), leading to
smaller binaries.
With little extra effort, C++ types can be pickled and unpickled similar to regular
Python objects.
Simple package installation: pip install pybind11
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
ADVANTAGES
11
Clang/LLVM 3.3 or newer (for Apple clang 5.0.0 or newer)
GCC 4.8 or newer
Microsoft Visual Studio 2015 Update 3 or newer
Intel C++ compiler 16 or newer (15 with a workaround)
Cygwin/GCC (tested on 2.5.1)
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
SUPPORTED COMPILERS
CORE FEATURES
13
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FEATURES
Functions accepting and returning custom data structures per
value, reference, or pointer
Instance methods and static methods
Overloaded functions
Instance attributes and static attributes
Arbitrary exception types
Enumerations
Callbacks
14
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FEATURES
Iterators and ranges
Custom operators
Single and multiple inheritance
STL data structures
Iterators and ranges
Smart pointers with reference counting like std::shared_ptr
Internal references with correct reference counting
C++ classes with virtual (and pure virtual) methods can be extended
in Python
DETAILS
16
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
SIMPLE EXAMPLE
#include <pybind11pybind11.h>
int add(int i, int j)
{
return i + j;
}
PYBIND11_MODULE(pybind_integration, m)
{
m.doc() = "pybind11 example plugin"; // optional docstring
m.def("add", &add, "Adds two numbers");
}
17
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
SIMPLE EXAMPLE
#include <pybind11pybind11.h>
PYBIND11_MODULE(pybind_integration, m)
{
m.doc() = "pybind11 example plugin"; // optional docstring
m.def("add", [] (int i, int j) {return i + j;},"Adds two numbers“);
}
C++11
18
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
SIMPLE EXAMPLE
>>> import pybind_integration
>>> add = pybind_integration.add
>>> add(2, 5)
7L
>>> help(add)
Help on built - in function add in module pybind_integration:
add(...)
add(arg0: int, arg1: int) -> int
Adds two numbers
>>> add(4.5, 5.5)
Traceback(most recent call last):
...
...
add(4.5, 5.5)
TypeError: add(): incompatible function arguments. The following argument types are supported:
1.(arg0: int, arg1: int) -> int
Invoked with: 4.5, 5.5
19
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
SIMPLE EXAMPLE
>>> import pybind_integration
>>> add = pybind_integration.add
>>> add(2, 5)
7L
>>> help(add)
Help on built - in function add in module pybind_integration:
add(...)
add(arg0: int, arg1: int) -> int
Adds two numbers
>>> add(4.5, 5.5)
Traceback(most recent call last):
...
...
add(4.5, 5.5)
TypeError: add(): incompatible function arguments. The following argument types are supported:
1.(arg0: int, arg1: int) -> int
Invoked with: 4.5, 5.5
20
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
SIMPLE EXAMPLE
>>> import pybind_integration
>>> add = pybind_integration.add
>>> add(2, 5)
7L
>>> help(add)
Help on built - in function add in module pybind_integration:
add(...)
add(arg0: int, arg1: int) -> int
Adds two numbers
>>> add(4.5, 5.5)
Traceback(most recent call last):
...
...
add(4.5, 5.5)
TypeError: add(): incompatible function arguments. The following argument types
are supported:
1.(arg0: int, arg1: int) -> int
Invoked with: 4.5, 5.5
21
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
BUILDING A MODULE
Linux
$ c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes`
pybind_integration.cpp -o pybind_integration`python3-config --extension-suffix`
Mac OS
$ c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 --
includes` pybind_integration.cpp -o pybind_integration`python3-config --extension-suffix`
Windows
22
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
BUILDING A MODULE
Linux
$ c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` pybind_integration.cpp –o pybind_integration`python3-config
--extension-suffix`
Mac OS
$ c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 --includes` pybind_integration.cpp -o
pybind_integration`python3-config --extension-suffix`
Windows Cmake
cmake_minimum_required(VERSION 2.8.12)
set(PYBIND11_CPP_STANDARD /std:c++11)
set(PYBIND11_PYTHON_VERSION=3.6)
project(pybind_integration)
add_subdirectory(pybind11)
pybind11_add_module(pybind_integration MODULE pybind_integration.cpp)
23
C++ COREHARD AUTUMN 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
BUILDING A MODULE
Building with setuptools
https://github.com/pybind/python_example
Building with cppimport
https://github.com/tbenthompson/cppimport
Generating binding code automatically(LLVM/Clang)
http://cppbinder.readthedocs.io/en/latest/about.html
24
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <string>
#define INITIAL_LIVES 3u
struct Tank {
std::string name;
unsigned lives;
int x;
int y;
};
25
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <pybind11pybind11.h>
PYBIND11_MODULE(tank, m) {
pybind11::class_<Tank>(m, "Tank")
.def_readonly("name", &Tank::name)
.def_readonly("lives", &Tank::lives)
.def_readonly("x", &Tank::x)
.def_readonly("y", &Tank::y);
}
pybind11
26
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <pybind11pybind11.h>
PYBIND11_MODULE(tank, m) {
pybind11::class_<Tank>(m, "Tank")
.def_readonly("name", &Tank::name)
.def_readwrite("lives", &Tank::lives)
.def_readwrite("x", &Tank::x)
.def_readwrite("y", &Tank::y);
}
pybind11
27
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <string>
#define INITIAL_LIVES 3u
struct Tank {
std::string name;
unsigned lives;
int x;
int y;
Tank(std::string name_, unsigned lives_ = INITIAL_LIVES, int x_ = 0, int y_ = 0)
: name{ name_ }, lives{ lives_ }, x{ x_ }, y{ y_ }
{}
Tank() : Tank("IS") {}
};
28
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <pybind11pybind11.h>
PYBIND11_MODULE(tank, m) {
pybind11::class_<Tank>(m, "Tank")
.def(pybind11::init<>())
.def(pybind11::init<std::string>())
.def(pybind11::init<std::string, unsigned>())
.def(pybind11::init<std::string, unsigned, int>())
.def(pybind11::init<std::string, unsigned, int, int>())
.def_readonly("name", &Tank::name)
.def_readonly("lives", &Tank::lives)
.def_readonly("x", &Tank::x)
.def_readonly("y", &Tank::y);
}
pybind11
29
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <string>
#define INITIAL_LIVES 3u
struct Tank {
std::string name;
unsigned lives;
int x;
int y;
Tank(std::string name_, unsigned lives_ = INITIAL_LIVES, int x_ = 0, int y_ = 0)
: name{ name_ }, lives{ lives_ }, x{ x_ }, y{ y_ }
{}
Tank() : Tank("IS")
{}
bool is_dead() const { return lives == 0u; }
};
30
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <pybind11pybind11.h>
PYBIND11_MODULE(tank, m) {
pybind11::class_<Tank>(m, "Tank")
.def(pybind11::init<>())
.def(pybind11::init<std::string>())
.def(pybind11::init<std::string, unsigned>())
.def(pybind11::init<std::string, unsigned, int>())
.def(pybind11::init<std::string, unsigned, int, int>())
.def_readonly("name", &Tank::name)
.def_readonly("lives", &Tank::lives)
.def_readonly("x", &Tank::x)
.def_readonly("y", &Tank::y)
.def_property_readonly("is_dead", &Tank::is_dead)
}
pybind11
31
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <string>
#define INITIAL_LIVES 3u
struct Tank {
std::string name;
unsigned lives;
int x;
int y;
Tank(std::string name_, unsigned lives_ = INITIAL_LIVES, int x_ = 0, int y_ = 0)
: name{ name_ }, lives{ lives_ }, x{ x_ }, y{ y_ }
{}
Tank() : Tank("IS")
{}
bool is_dead() const { return lives == 0u; }
std::string to_string() const {
return "<" + name + ":" + std::to_string(lives) +
" [" + std::to_string(x) + ", " + std::to_string(y) + "]>";
}
};
32
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <pybind11pybind11.h>
PYBIND11_MODULE(tank, m) {
pybind11::class_<Tank>(m, "Tank")
.def(pybind11::init<>())
.def(pybind11::init<std::string>())
.def(pybind11::init<std::string, unsigned>())
.def(pybind11::init<std::string, unsigned, int>())
.def(pybind11::init<std::string, unsigned, int, int>())
.def_readonly("name", &Tank::name)
.def_readonly("lives", &Tank::lives)
.def_readonly("x", &Tank::x)
.def_readonly("y", &Tank::y)
.def_property_readonly("is_dead", &Tank::is_dead)
.def("__repr__", &Tank::to_string);
}
pybind11
33
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <string>
#define INITIAL_LIVES 3u
struct Tank {
std::string name;
unsigned lives;
int x;
int y;
Tank(std::string name_, unsigned lives_ = INITIAL_LIVES, int x_ = 0, int y_ = 0)
: name{ name_ }, lives{ lives_ }, x{ x_ }, y{ y_ }
{}
Tank() : Tank("IS")
{}
bool is_dead() const { return lives == 0u; }
std::string to_string() const {
return "<" + name + ":" + std::to_string(lives) + " [" + std::to_string(x) + ", " + std::to_string(y) + "]>";
}
};
bool operator==(const Tank& t1, const Tank& t2) {
return t1.name == t2.name;
}
34
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <pybind11pybind11.h>
PYBIND11_MODULE(tank, m) {
pybind11::class_<Tank>(m, "Tank")
.def(pybind11::init<>())
.def(pybind11::init<std::string>())
.def(pybind11::init<std::string, unsigned>())
.def(pybind11::init<std::string, unsigned, int>())
.def(pybind11::init<std::string, unsigned, int, int>())
.def_readonly("name", &Tank::name)
.def_readonly("lives", &Tank::lives)
.def_readonly("x", &Tank::x)
.def_readonly("y", &Tank::y)
.def_property_readonly("is_dead", &Tank::is_dead)
.def("__eq__", [](const Tank& l, const Tank& r) { return l == r; }, pybind11::is_operator())
.def("__repr__", &Tank::to_string);
}
pybind11
35
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
#include <pybind11pybind11.h>
#include <pybind11/operators.h>
PYBIND11_MODULE(tank, m) {
pybind11::class_<Tank>(m, "Tank")
.def(pybind11::init<>())
.def(pybind11::init<std::string>())
.def(pybind11::init<std::string, unsigned>())
.def(pybind11::init<std::string, unsigned, int>())
.def(pybind11::init<std::string, unsigned, int, int>())
.def_readonly("name", &Tank::name)
.def_readonly("lives", &Tank::lives)
.def_readonly("x", &Tank::x)
.def_readonly("y", &Tank::y)
.def_property_readonly("is_dead", &Tank::is_dead)
.def(pybind11::self == pybind11::self)
.def("__repr__", &Tank::to_string);
}
pybind11
36
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
PYBIND11_MODULE(tank, m) {
pybind11::class_<Tank>(m, "Tank")
...
.def(pybind11::pickle(
[](const Tank& t) { /* __getstate__ */
return pybind11::make_tuple(t.name, t.lives, t.x, t.y);
},
[](pybind11::tuple t) {/* __setstate__ */
if (t.size() != 4) throw std::runtime_error("Invalid data!");
Tank tank(t[0].cast<std::string>(), t[1].cast<unsigned>(), t[2].cast<int>(), t[3].cast<int>());
return tank;
}
));
}
pybind11
37
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CLASS EXAMPLE
>>> from tank import Tank
>>> Tank()
<IS:3 [0, 0]>
>>> is2 = Tank("IS-2")
>>> is2.name
'IS-2'
>>> is2.is_dead
False
>>> is2 == Tank()
False
python
38
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Docstrings can be set by passing string literals to def().
Arguments can be named via py::arg("...").
m.def("shoot", [](const std::string& name) {
pybind11::print("Didn't penetrate the armor of " + name + ".");
},
"Shoot a tank.", pybind11::arg("name")
);
39
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Docstrings can be set by passing string literals to def().
Arguments can be named via py::arg("...").
m.def("shoot", [](const std::string& name) {
pybind11::print("Didn't penetrate the armor of " + name + ".");
},
"Shoot a tank.", pybind11::arg("name")
);
>>> shoot('IS')
Didn't penetrate the armor of IS.
>>> help(shoot)
Help on built-in function shoot in module tank:
shoot(...)
shoot(name: unicode) -> None
Shoot a tank.
40
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Default arguments.
m.def("shoot", [](const std::string& name, unsigned times) {
if (times > 3)
pybind11::print(“Kill " + name + ".")
else
pybind11::print("Didn't penetrate " + name + ".");
},
"Shoot a tank.", pybind11::arg("name"), pybind11::arg(“times") = 1
);
41
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Default arguments.
m.def("shoot", [](const std::string& name, unsigned times) {
if (times > 3)
pybind11::print(“Kill " + name + ".")
else
pybind11::print("Didn't penetrate " + name + ".");
},
"Shoot a tank.", pybind11::arg("name"), pybind11::arg(“times") = 1
);
>>> shoot("IS")
Didn't penetrate IS.
>>> shoot("IS-2", 4)
Kill IS-2.
42
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Variadic positional and keyword arguments.
m.def("count_args", [](pybind11::args a, pybind11::kwargs kw) {
pybind11::print(a.size(), "args,", kw.size(), "kwargs");
});
>>> count_args(14, 10, 2017, corehard='autumn')
3 args, 1 kwargs
43
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Python objects as arguments.
m.def("count_tanks", [](pybind11::list list) {
int n = 0;
for (auto item : list)
if (pybind11::isinstance<Tank>(item))
++n;
return n;
});
>>> from tank import count_tanks
>>> count_tanks([Tank("IS-2"), Tank(), 1, "IS-7"])
2
44
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Function overloading .
m.def("go_to", [](int x, int y) { return "go_to int"; });
m.def("go_to", [](double x, double y) { return "go_to double"; });
>>> go_to(25, 4)
'go_to int'
>>> go_to(3.14, 3.14)
'go_to double'
45
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Callbacks.
int func_arg(const std::function<int(int)> &f) {
return f(10);
}
46
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Callbacks.
int func_arg(const std::function<int(int)> &f) {
return f(10);
}
std::function<int(int)> func_ret(const std::function<int(int)> &f) {
return [f](int i) {return f(i) + 1;};
}
47
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Callbacks.
int func_arg(const std::function<int(int)> &f) {
return f(10);
}
std::function<int(int)> func_ret(const std::function<int(int)> &f) {
return [f](int i) {return f(i) + 1;};
}
pybind11::cpp_function func_cpp() {
return pybind11::cpp_function(
[](int i) { return i + 1; }, pybind11::arg("number")
);
}
48
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Callbacks.
int func_arg(const std::function<int(int)> &f) {
return f(10);
}
std::function<int(int)> func_ret(const std::function<int(int)> &f) {
return [f](int i) {return f(i) + 1;};
}
pybind11::cpp_function func_cpp() {
return pybind11::cpp_function(
[](int i) { return i + 1; }, pybind11::arg("number")
);
}
#include <pybind11/functional.h>
PYBIND11_MODULE(example, m) {
m.def("func_arg", &func_arg);
m.def("func_ret", &func_ret);
m.def("func_cpp", &func_cpp);
}
49
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
FUNCTIONS
Callbacks.
>>> import example
>>> def square(i):
... return i * i
...
>>> example.func_arg(square)
100L
>>> square_plus_1 = example.func_ret(square)
>>> square_plus_1(4)
17L
>>> plus_1 = func_cpp()
>>> plus_1(number=43)
44L
50
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
ENUMS
struct Tank {
...
enum Type { HEAVY, LIGHT };
};
pybind11::class_<Tank> cls(m, "Tank");
pybind11::enum_<Tank::Type>(cls, "Type")
.value(“HEAVY", Tank::Type::HEAVY)
.value("LIGHT", Tank::Type::LIGHT)
.export_values();
Notes: pybind11 enums are not ints
51
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
EMBEDDING THE INTERPRETER
#include <pybind11/embed.h>
int main() {
pybind11::scoped_interpreter guard{}; // start the interpreter and keep it alive
pybind11::exec(R"(
kwargs = dict(name="IS", number=667)
message = "Shoot {name} with id {number}".format(**kwargs)
print(message)
)");
}
52
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
EMBEDDING THE INTERPRETER
cmake_minimum_required(VERSION 3.0)
project(embed_itnterpreter)
find_package(pybind11 REQUIRED) # or `add_subdirectory(pybind11)`
add_executable(embed_itnterpreter main.cpp)
target_link_libraries(embed_itnterpreter PRIVATE pybind11::embed)
53
C++ COREHARD SPRING 2017
IGOR SADCHENKO // C++ COREHARD // 14.10.17
EMBEDDING THE INTERPRETER
Importing modules
pybind11::module sys = pybind11::module::import("sys");
pybind11::print(sys.attr("path"));
Adding embedded modules
PYBIND11_EMBEDDED_MODULE(fast_calc, m) {
// 'm' is a 'py::module' which is used to bind functions and classes
m.def("add", [](int i, int j) {
return i + j;
});
}
auto fast_calc = pybind11::module::import("fast_calc");
auto result = fast_calc.attr("add")(1, 2).cast<int>();
SUMMARY
55
C++ COREHARD AUTUMN 2017 // SUMMARY
IGOR SADCHENKO // C++ COREHARD // 14.10.17
CONCLUSION
pybind11
• simple to use
• efficient
• supported by the community
56
C++ COREHARD SPRING 2017 //
IGOR SADCHENKO // C++ COREHARD // 14.10.17
LINKS
python
https://www.python.org
https://docs.python.org/3/extending/index.html
https://docs.python.org/3/c-api/index.html
pybind11
https://github.com/pybind/pybind11
http://pybind11.readthedocs.io/en/stable
THANK YOU FOR YOUR
ATTENTION!
IGOR SADCHENKO
software developer
+375 33 642 92 91
https://www.facebook.com/WargamingMinsk
ANY QUESTIONS?
igor.sadchenko@gmail.com
wargaming.com
https://www.linkedin.com/company/wargaming-net

More Related Content

What's hot

Marp入門
Marp入門Marp入門
Marp入門
Rui Watanabe
 
LR parsing
LR parsingLR parsing
LR parsing
ichikaz3
 
Polyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGAPolyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGA
ryos36
 
Enumerable lazy について
Enumerable lazy についてEnumerable lazy について
Enumerable lazy についてTomoya Kawanishi
 
スーパーコンピュータとアプリケーションの性能
スーパーコンピュータとアプリケーションの性能スーパーコンピュータとアプリケーションの性能
スーパーコンピュータとアプリケーションの性能
RCCSRENKEI
 
(公開版)FPGAエクストリームコンピューティング2017
(公開版)FPGAエクストリームコンピューティング2017 (公開版)FPGAエクストリームコンピューティング2017
(公開版)FPGAエクストリームコンピューティング2017
Hiroki Nakahara
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
Tomoya Kawanishi
 
ELFの動的リンク
ELFの動的リンクELFの動的リンク
ELFの動的リンク
7shi
 
x86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNT
takesako
 
Coqチュートリアル
CoqチュートリアルCoqチュートリアル
Coqチュートリアル
Yoshihiro Mizoguchi
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
Genya Murakami
 
GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)
智啓 出川
 
CPP Language Basics - Reference
CPP Language Basics - ReferenceCPP Language Basics - Reference
CPP Language Basics - Reference
Mohammed Sikander
 
いつやるの?Git入門
いつやるの?Git入門いつやるの?Git入門
いつやるの?Git入門
Masakazu Matsushita
 
Gitの便利ワザ
Gitの便利ワザGitの便利ワザ
Gitの便利ワザ
ktateish
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろうKota Mizushima
 
Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2 「エッジAIモダン計測制御の世界」オ...
Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2  「エッジAIモダン計測制御の世界」オ...Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2  「エッジAIモダン計測制御の世界」オ...
Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2 「エッジAIモダン計測制御の世界」オ...
Mr. Vengineer
 
ROSチュートリアル ROBOMECH2018
ROSチュートリアル ROBOMECH2018ROSチュートリアル ROBOMECH2018
ROSチュートリアル ROBOMECH2018
Ryuichi Ueda
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎
信之 岩永
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 

What's hot (20)

Marp入門
Marp入門Marp入門
Marp入門
 
LR parsing
LR parsingLR parsing
LR parsing
 
Polyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGAPolyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGA
 
Enumerable lazy について
Enumerable lazy についてEnumerable lazy について
Enumerable lazy について
 
スーパーコンピュータとアプリケーションの性能
スーパーコンピュータとアプリケーションの性能スーパーコンピュータとアプリケーションの性能
スーパーコンピュータとアプリケーションの性能
 
(公開版)FPGAエクストリームコンピューティング2017
(公開版)FPGAエクストリームコンピューティング2017 (公開版)FPGAエクストリームコンピューティング2017
(公開版)FPGAエクストリームコンピューティング2017
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
 
ELFの動的リンク
ELFの動的リンクELFの動的リンク
ELFの動的リンク
 
x86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNT
 
Coqチュートリアル
CoqチュートリアルCoqチュートリアル
Coqチュートリアル
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)GPGPU Seminar (PyCUDA)
GPGPU Seminar (PyCUDA)
 
CPP Language Basics - Reference
CPP Language Basics - ReferenceCPP Language Basics - Reference
CPP Language Basics - Reference
 
いつやるの?Git入門
いつやるの?Git入門いつやるの?Git入門
いつやるの?Git入門
 
Gitの便利ワザ
Gitの便利ワザGitの便利ワザ
Gitの便利ワザ
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2 「エッジAIモダン計測制御の世界」オ...
Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2  「エッジAIモダン計測制御の世界」オ...Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2  「エッジAIモダン計測制御の世界」オ...
Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2 「エッジAIモダン計測制御の世界」オ...
 
ROSチュートリアル ROBOMECH2018
ROSチュートリアル ROBOMECH2018ROSチュートリアル ROBOMECH2018
ROSチュートリアル ROBOMECH2018
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 

Viewers also liked

Benchmark it
Benchmark itBenchmark it
Benchmark it
corehard_by
 
Battle: BDD vs notBDD
Battle: BDD vs notBDDBattle: BDD vs notBDD
Battle: BDD vs notBDD
COMAQA.BY
 
Abseil - let the savior come?
Abseil - let the savior come?Abseil - let the savior come?
Abseil - let the savior come?
corehard_by
 
Analysis and interpretation of monitoring data
Analysis and interpretation of monitoring dataAnalysis and interpretation of monitoring data
Analysis and interpretation of monitoring data
corehard_by
 
Ускоряем сборку С++ проектов. Практика использования unity-сборок
Ускоряем сборку С++ проектов. Практика использования unity-сборокУскоряем сборку С++ проектов. Практика использования unity-сборок
Ускоряем сборку С++ проектов. Практика использования unity-сборок
corehard_by
 
(Не)чёткий поиск
(Не)чёткий поиск(Не)чёткий поиск
(Не)чёткий поиск
corehard_by
 
Restinio - header-only http and websocket server
Restinio - header-only http and websocket serverRestinio - header-only http and websocket server
Restinio - header-only http and websocket server
corehard_by
 
Actors for fun and profit
Actors for fun and profitActors for fun and profit
Actors for fun and profit
corehard_by
 
C++ в играх, больших и не очень
C++ в играх, больших и не оченьC++ в играх, больших и не очень
C++ в играх, больших и не очень
corehard_by
 
Субъекторная модель
Субъекторная модельСубъекторная модель
Субъекторная модель
corehard_by
 
MxxRu::externals: Repositoryless Dependency Manager
MxxRu::externals: Repositoryless Dependency ManagerMxxRu::externals: Repositoryless Dependency Manager
MxxRu::externals: Repositoryless Dependency Manager
corehard_by
 
Обработка потока данных на примере deep packet inspection: внутренняя архитек...
Обработка потока данных на примере deep packet inspection: внутренняя архитек...Обработка потока данных на примере deep packet inspection: внутренняя архитек...
Обработка потока данных на примере deep packet inspection: внутренняя архитек...
corehard_by
 
C++Now Trip Report
C++Now Trip ReportC++Now Trip Report
C++Now Trip Report
corehard_by
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
corehard_by
 
C++ and Assembly: Debugging and Reverse Engineering
C++ and Assembly: Debugging and Reverse EngineeringC++ and Assembly: Debugging and Reverse Engineering
C++ and Assembly: Debugging and Reverse Engineering
corehard_by
 
C++ in kernel mode
C++ in kernel modeC++ in kernel mode
C++ in kernel mode
corehard_by
 
The beast is becoming functional
The beast is becoming functionalThe beast is becoming functional
The beast is becoming functional
corehard_by
 
Слои тестового фрамеворка. Что? Где? Когда?
Слои тестового фрамеворка. Что? Где? Когда?Слои тестового фрамеворка. Что? Где? Когда?
Слои тестового фрамеворка. Что? Где? Когда?
COMAQA.BY
 
Метаданные для кластера: гонка key-value-героев / Руслан Рагимов, Светлана Ла...
Метаданные для кластера: гонка key-value-героев / Руслан Рагимов, Светлана Ла...Метаданные для кластера: гонка key-value-героев / Руслан Рагимов, Светлана Ла...
Метаданные для кластера: гонка key-value-героев / Руслан Рагимов, Светлана Ла...
Ontico
 
Честное перформанс-тестирование / Дмитрий Пивоваров (ZeroTurnaround)
Честное перформанс-тестирование / Дмитрий Пивоваров (ZeroTurnaround)Честное перформанс-тестирование / Дмитрий Пивоваров (ZeroTurnaround)
Честное перформанс-тестирование / Дмитрий Пивоваров (ZeroTurnaround)
Ontico
 

Viewers also liked (20)

Benchmark it
Benchmark itBenchmark it
Benchmark it
 
Battle: BDD vs notBDD
Battle: BDD vs notBDDBattle: BDD vs notBDD
Battle: BDD vs notBDD
 
Abseil - let the savior come?
Abseil - let the savior come?Abseil - let the savior come?
Abseil - let the savior come?
 
Analysis and interpretation of monitoring data
Analysis and interpretation of monitoring dataAnalysis and interpretation of monitoring data
Analysis and interpretation of monitoring data
 
Ускоряем сборку С++ проектов. Практика использования unity-сборок
Ускоряем сборку С++ проектов. Практика использования unity-сборокУскоряем сборку С++ проектов. Практика использования unity-сборок
Ускоряем сборку С++ проектов. Практика использования unity-сборок
 
(Не)чёткий поиск
(Не)чёткий поиск(Не)чёткий поиск
(Не)чёткий поиск
 
Restinio - header-only http and websocket server
Restinio - header-only http and websocket serverRestinio - header-only http and websocket server
Restinio - header-only http and websocket server
 
Actors for fun and profit
Actors for fun and profitActors for fun and profit
Actors for fun and profit
 
C++ в играх, больших и не очень
C++ в играх, больших и не оченьC++ в играх, больших и не очень
C++ в играх, больших и не очень
 
Субъекторная модель
Субъекторная модельСубъекторная модель
Субъекторная модель
 
MxxRu::externals: Repositoryless Dependency Manager
MxxRu::externals: Repositoryless Dependency ManagerMxxRu::externals: Repositoryless Dependency Manager
MxxRu::externals: Repositoryless Dependency Manager
 
Обработка потока данных на примере deep packet inspection: внутренняя архитек...
Обработка потока данных на примере deep packet inspection: внутренняя архитек...Обработка потока данных на примере deep packet inspection: внутренняя архитек...
Обработка потока данных на примере deep packet inspection: внутренняя архитек...
 
C++Now Trip Report
C++Now Trip ReportC++Now Trip Report
C++Now Trip Report
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
 
C++ and Assembly: Debugging and Reverse Engineering
C++ and Assembly: Debugging and Reverse EngineeringC++ and Assembly: Debugging and Reverse Engineering
C++ and Assembly: Debugging and Reverse Engineering
 
C++ in kernel mode
C++ in kernel modeC++ in kernel mode
C++ in kernel mode
 
The beast is becoming functional
The beast is becoming functionalThe beast is becoming functional
The beast is becoming functional
 
Слои тестового фрамеворка. Что? Где? Когда?
Слои тестового фрамеворка. Что? Где? Когда?Слои тестового фрамеворка. Что? Где? Когда?
Слои тестового фрамеворка. Что? Где? Когда?
 
Метаданные для кластера: гонка key-value-героев / Руслан Рагимов, Светлана Ла...
Метаданные для кластера: гонка key-value-героев / Руслан Рагимов, Светлана Ла...Метаданные для кластера: гонка key-value-героев / Руслан Рагимов, Светлана Ла...
Метаданные для кластера: гонка key-value-героев / Руслан Рагимов, Светлана Ла...
 
Честное перформанс-тестирование / Дмитрий Пивоваров (ZeroTurnaround)
Честное перформанс-тестирование / Дмитрий Пивоваров (ZeroTurnaround)Честное перформанс-тестирование / Дмитрий Пивоваров (ZeroTurnaround)
Честное перформанс-тестирование / Дмитрий Пивоваров (ZeroTurnaround)
 

Similar to Mixing C++ & Python II: Pybind11

High performance web programming with C++14
High performance web programming with C++14High performance web programming with C++14
High performance web programming with C++14
Matthieu Garrigues
 
SciPy22 - Building binary extensions with pybind11, scikit build, and cibuild...
SciPy22 - Building binary extensions with pybind11, scikit build, and cibuild...SciPy22 - Building binary extensions with pybind11, scikit build, and cibuild...
SciPy22 - Building binary extensions with pybind11, scikit build, and cibuild...
Henry Schreiner
 
High scalable applications with Python
High scalable applications with PythonHigh scalable applications with Python
High scalable applications with Python
Giuseppe Broccolo
 
carrow - Go bindings to Apache Arrow via C++-API
carrow - Go bindings to Apache Arrow via C++-APIcarrow - Go bindings to Apache Arrow via C++-API
carrow - Go bindings to Apache Arrow via C++-API
Yoni Davidson
 
Cython - close to metal Python
Cython - close to metal PythonCython - close to metal Python
Cython - close to metal Python
Taras Lyapun
 
PyCon2022 - Building Python Extensions
PyCon2022 - Building Python ExtensionsPyCon2022 - Building Python Extensions
PyCon2022 - Building Python Extensions
Henry Schreiner
 
Implementing an interface in r to communicate with programmable fabric in a x...
Implementing an interface in r to communicate with programmable fabric in a x...Implementing an interface in r to communicate with programmable fabric in a x...
Implementing an interface in r to communicate with programmable fabric in a x...
Vincent Claes
 
How c/c++ works
How c/c++ worksHow c/c++ works
How c/c++ works
Md. Ekhlasur Rahman
 
Mender.io | Develop embedded applications faster | Comparing C and Golang
Mender.io | Develop embedded applications faster | Comparing C and GolangMender.io | Develop embedded applications faster | Comparing C and Golang
Mender.io | Develop embedded applications faster | Comparing C and Golang
Mender.io
 
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
Alexandre Gouaillard
 
C++17 now
C++17 nowC++17 now
C++17 now
corehard_by
 
Pypy is-it-ready-for-production-the-sequel
Pypy is-it-ready-for-production-the-sequelPypy is-it-ready-for-production-the-sequel
Pypy is-it-ready-for-production-the-sequel
Mark Rees
 
Debugging Python with gdb
Debugging Python with gdbDebugging Python with gdb
Debugging Python with gdb
Roman Podoliaka
 
Brief Introduction to Cython
Brief Introduction to CythonBrief Introduction to Cython
Brief Introduction to Cython
Aleksandar Jelenak
 
InterPlanetary File System (IPFS)
InterPlanetary File System (IPFS)InterPlanetary File System (IPFS)
InterPlanetary File System (IPFS)
Gene Leybzon
 
Boost.Python: C++ and Python Integration
Boost.Python: C++ and Python IntegrationBoost.Python: C++ and Python Integration
Boost.Python: C++ and Python Integration
GlobalLogic Ukraine
 
End to-end ml pipelines with beam, flink, tensor flow, and hopsworks (beam su...
End to-end ml pipelines with beam, flink, tensor flow, and hopsworks (beam su...End to-end ml pipelines with beam, flink, tensor flow, and hopsworks (beam su...
End to-end ml pipelines with beam, flink, tensor flow, and hopsworks (beam su...
Theofilos Kakantousis
 
Writing an Ostinato Protocol Builder [FOSDEM 2021]
Writing an Ostinato Protocol Builder [FOSDEM 2021]Writing an Ostinato Protocol Builder [FOSDEM 2021]
Writing an Ostinato Protocol Builder [FOSDEM 2021]
pstavirs
 
Griffon Topic2 Presentation (Tia)
Griffon Topic2 Presentation (Tia)Griffon Topic2 Presentation (Tia)
Griffon Topic2 Presentation (Tia)
Nat Weerawan
 
Report on c and c++
Report on c and c++Report on c and c++
Report on c and c++
oggyrao
 

Similar to Mixing C++ & Python II: Pybind11 (20)

High performance web programming with C++14
High performance web programming with C++14High performance web programming with C++14
High performance web programming with C++14
 
SciPy22 - Building binary extensions with pybind11, scikit build, and cibuild...
SciPy22 - Building binary extensions with pybind11, scikit build, and cibuild...SciPy22 - Building binary extensions with pybind11, scikit build, and cibuild...
SciPy22 - Building binary extensions with pybind11, scikit build, and cibuild...
 
High scalable applications with Python
High scalable applications with PythonHigh scalable applications with Python
High scalable applications with Python
 
carrow - Go bindings to Apache Arrow via C++-API
carrow - Go bindings to Apache Arrow via C++-APIcarrow - Go bindings to Apache Arrow via C++-API
carrow - Go bindings to Apache Arrow via C++-API
 
Cython - close to metal Python
Cython - close to metal PythonCython - close to metal Python
Cython - close to metal Python
 
PyCon2022 - Building Python Extensions
PyCon2022 - Building Python ExtensionsPyCon2022 - Building Python Extensions
PyCon2022 - Building Python Extensions
 
Implementing an interface in r to communicate with programmable fabric in a x...
Implementing an interface in r to communicate with programmable fabric in a x...Implementing an interface in r to communicate with programmable fabric in a x...
Implementing an interface in r to communicate with programmable fabric in a x...
 
How c/c++ works
How c/c++ worksHow c/c++ works
How c/c++ works
 
Mender.io | Develop embedded applications faster | Comparing C and Golang
Mender.io | Develop embedded applications faster | Comparing C and GolangMender.io | Develop embedded applications faster | Comparing C and Golang
Mender.io | Develop embedded applications faster | Comparing C and Golang
 
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
IIT-RTC 2017 Qt WebRTC Tutorial (Qt Janus Client)
 
C++17 now
C++17 nowC++17 now
C++17 now
 
Pypy is-it-ready-for-production-the-sequel
Pypy is-it-ready-for-production-the-sequelPypy is-it-ready-for-production-the-sequel
Pypy is-it-ready-for-production-the-sequel
 
Debugging Python with gdb
Debugging Python with gdbDebugging Python with gdb
Debugging Python with gdb
 
Brief Introduction to Cython
Brief Introduction to CythonBrief Introduction to Cython
Brief Introduction to Cython
 
InterPlanetary File System (IPFS)
InterPlanetary File System (IPFS)InterPlanetary File System (IPFS)
InterPlanetary File System (IPFS)
 
Boost.Python: C++ and Python Integration
Boost.Python: C++ and Python IntegrationBoost.Python: C++ and Python Integration
Boost.Python: C++ and Python Integration
 
End to-end ml pipelines with beam, flink, tensor flow, and hopsworks (beam su...
End to-end ml pipelines with beam, flink, tensor flow, and hopsworks (beam su...End to-end ml pipelines with beam, flink, tensor flow, and hopsworks (beam su...
End to-end ml pipelines with beam, flink, tensor flow, and hopsworks (beam su...
 
Writing an Ostinato Protocol Builder [FOSDEM 2021]
Writing an Ostinato Protocol Builder [FOSDEM 2021]Writing an Ostinato Protocol Builder [FOSDEM 2021]
Writing an Ostinato Protocol Builder [FOSDEM 2021]
 
Griffon Topic2 Presentation (Tia)
Griffon Topic2 Presentation (Tia)Griffon Topic2 Presentation (Tia)
Griffon Topic2 Presentation (Tia)
 
Report on c and c++
Report on c and c++Report on c and c++
Report on c and c++
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
corehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
corehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
corehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
corehard_by
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
corehard_by
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
corehard_by
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
corehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
corehard_by
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
corehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 

Recently uploaded

CAKE: Sharing Slices of Confidential Data on Blockchain
CAKE: Sharing Slices of Confidential Data on BlockchainCAKE: Sharing Slices of Confidential Data on Blockchain
CAKE: Sharing Slices of Confidential Data on Blockchain
Claudio Di Ciccio
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdfAI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
Techgropse Pvt.Ltd.
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
Mariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceXMariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceX
Mariano Tinti
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
Zilliz
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
Tomaz Bratanic
 
Infrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI modelsInfrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI models
Zilliz
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 

Recently uploaded (20)

CAKE: Sharing Slices of Confidential Data on Blockchain
CAKE: Sharing Slices of Confidential Data on BlockchainCAKE: Sharing Slices of Confidential Data on Blockchain
CAKE: Sharing Slices of Confidential Data on Blockchain
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdfAI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
AI-Powered Food Delivery Transforming App Development in Saudi Arabia.pdf
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
Mariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceXMariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceX
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
 
Infrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI modelsInfrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI models
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 

Mixing C++ & Python II: Pybind11

  • 1. MIXING C++ & PYTHON II: PYBIND11 IGOR SADCHENKO IGOR.SADCHENKO@GMAIL.COM
  • 3. 2 Python is a high-level general purpose programming language that focuses on developer productivity improving and code readability. The syntax of the core Python is minimalistic. At the same time, the standard library includes a large amount of useful functions. Python supports multiple programming paradigms, including structured, object-oriented, functional, imperative, and aspect-oriented. The main architectural features – dynamic typing, automatic memory management, full introspection, handling mechanism exception, multi- threaded computing and comfortable high-level data structure support. The disadvantages include low performance and the lack of real multi- threading (GIL) C++ COREHARD AUTUMN 2017 // IGOR SADCHENKO // C++ COREHARD // 14.10.17 PYTHON
  • 5. 4 C++ COREHARD AUTUMN 2017 // IGOR SADCHENKO // C++ COREHARD // 14.10.17 C++ & PYTHON Python and C++ easily complement each other. Python gives you rapid development and flexibility C++ gives you speed and industrial strength tools.
  • 6. 5 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17
  • 8. 7 pybind11 is a lightweight header-only library that exposes C++ types in Python and vice versa, mainly to create Python bindings of existing C++ code. Think of this library as a tiny self-contained version of Boost.Python with everything stripped away that isn’t relevant for binding generation. Without comments, the core header files only require ~4K lines of code and depend on Python (2.7 or 3.x, or PyPy2.7 >= 5.7) and the C++ standard library. This compact implementation was possible thanks to some of the new C++11 language features (specifically: tuples, lambda functions and variadic templates). Since its creation, this library has grown beyond Boost.Python in many ways, leading to dramatically simpler binding code in many common situations. C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 PYBIND11
  • 9. 8 Boost.Python pybind11 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 PYBIND11
  • 10. 9 Python 2.7, 3.x, and PyPy (PyPy2.7 >= 5.7) are supported with an implementation- agnostic interface. It is possible to bind C++11 lambda functions with captured variables. Using move constructors/assignment whenever possible to efficiently transfer custom data types. It's easy to expose the internal storage of custom data types through Pythons' buffer protocols. Automatic vectorization of functions for NumPy array arguments. Python's slice-based access and assignment operations can be supported with just a few lines of code. C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 ADVANTAGES
  • 11. 10 Everything is contained in just a few header files. Binaries and compile time are generally smaller by factor 2 vs. to equivalent bindings of Boost.Python. Function signatures are precomputed at compile time (using constexpr), leading to smaller binaries. With little extra effort, C++ types can be pickled and unpickled similar to regular Python objects. Simple package installation: pip install pybind11 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 ADVANTAGES
  • 12. 11 Clang/LLVM 3.3 or newer (for Apple clang 5.0.0 or newer) GCC 4.8 or newer Microsoft Visual Studio 2015 Update 3 or newer Intel C++ compiler 16 or newer (15 with a workaround) Cygwin/GCC (tested on 2.5.1) C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 SUPPORTED COMPILERS
  • 14. 13 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FEATURES Functions accepting and returning custom data structures per value, reference, or pointer Instance methods and static methods Overloaded functions Instance attributes and static attributes Arbitrary exception types Enumerations Callbacks
  • 15. 14 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FEATURES Iterators and ranges Custom operators Single and multiple inheritance STL data structures Iterators and ranges Smart pointers with reference counting like std::shared_ptr Internal references with correct reference counting C++ classes with virtual (and pure virtual) methods can be extended in Python
  • 17. 16 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 SIMPLE EXAMPLE #include <pybind11pybind11.h> int add(int i, int j) { return i + j; } PYBIND11_MODULE(pybind_integration, m) { m.doc() = "pybind11 example plugin"; // optional docstring m.def("add", &add, "Adds two numbers"); }
  • 18. 17 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 SIMPLE EXAMPLE #include <pybind11pybind11.h> PYBIND11_MODULE(pybind_integration, m) { m.doc() = "pybind11 example plugin"; // optional docstring m.def("add", [] (int i, int j) {return i + j;},"Adds two numbers“); } C++11
  • 19. 18 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 SIMPLE EXAMPLE >>> import pybind_integration >>> add = pybind_integration.add >>> add(2, 5) 7L >>> help(add) Help on built - in function add in module pybind_integration: add(...) add(arg0: int, arg1: int) -> int Adds two numbers >>> add(4.5, 5.5) Traceback(most recent call last): ... ... add(4.5, 5.5) TypeError: add(): incompatible function arguments. The following argument types are supported: 1.(arg0: int, arg1: int) -> int Invoked with: 4.5, 5.5
  • 20. 19 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 SIMPLE EXAMPLE >>> import pybind_integration >>> add = pybind_integration.add >>> add(2, 5) 7L >>> help(add) Help on built - in function add in module pybind_integration: add(...) add(arg0: int, arg1: int) -> int Adds two numbers >>> add(4.5, 5.5) Traceback(most recent call last): ... ... add(4.5, 5.5) TypeError: add(): incompatible function arguments. The following argument types are supported: 1.(arg0: int, arg1: int) -> int Invoked with: 4.5, 5.5
  • 21. 20 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 SIMPLE EXAMPLE >>> import pybind_integration >>> add = pybind_integration.add >>> add(2, 5) 7L >>> help(add) Help on built - in function add in module pybind_integration: add(...) add(arg0: int, arg1: int) -> int Adds two numbers >>> add(4.5, 5.5) Traceback(most recent call last): ... ... add(4.5, 5.5) TypeError: add(): incompatible function arguments. The following argument types are supported: 1.(arg0: int, arg1: int) -> int Invoked with: 4.5, 5.5
  • 22. 21 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 BUILDING A MODULE Linux $ c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` pybind_integration.cpp -o pybind_integration`python3-config --extension-suffix` Mac OS $ c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 -- includes` pybind_integration.cpp -o pybind_integration`python3-config --extension-suffix` Windows
  • 23. 22 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 BUILDING A MODULE Linux $ c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` pybind_integration.cpp –o pybind_integration`python3-config --extension-suffix` Mac OS $ c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 --includes` pybind_integration.cpp -o pybind_integration`python3-config --extension-suffix` Windows Cmake cmake_minimum_required(VERSION 2.8.12) set(PYBIND11_CPP_STANDARD /std:c++11) set(PYBIND11_PYTHON_VERSION=3.6) project(pybind_integration) add_subdirectory(pybind11) pybind11_add_module(pybind_integration MODULE pybind_integration.cpp)
  • 24. 23 C++ COREHARD AUTUMN 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 BUILDING A MODULE Building with setuptools https://github.com/pybind/python_example Building with cppimport https://github.com/tbenthompson/cppimport Generating binding code automatically(LLVM/Clang) http://cppbinder.readthedocs.io/en/latest/about.html
  • 25. 24 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <string> #define INITIAL_LIVES 3u struct Tank { std::string name; unsigned lives; int x; int y; };
  • 26. 25 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <pybind11pybind11.h> PYBIND11_MODULE(tank, m) { pybind11::class_<Tank>(m, "Tank") .def_readonly("name", &Tank::name) .def_readonly("lives", &Tank::lives) .def_readonly("x", &Tank::x) .def_readonly("y", &Tank::y); } pybind11
  • 27. 26 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <pybind11pybind11.h> PYBIND11_MODULE(tank, m) { pybind11::class_<Tank>(m, "Tank") .def_readonly("name", &Tank::name) .def_readwrite("lives", &Tank::lives) .def_readwrite("x", &Tank::x) .def_readwrite("y", &Tank::y); } pybind11
  • 28. 27 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <string> #define INITIAL_LIVES 3u struct Tank { std::string name; unsigned lives; int x; int y; Tank(std::string name_, unsigned lives_ = INITIAL_LIVES, int x_ = 0, int y_ = 0) : name{ name_ }, lives{ lives_ }, x{ x_ }, y{ y_ } {} Tank() : Tank("IS") {} };
  • 29. 28 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <pybind11pybind11.h> PYBIND11_MODULE(tank, m) { pybind11::class_<Tank>(m, "Tank") .def(pybind11::init<>()) .def(pybind11::init<std::string>()) .def(pybind11::init<std::string, unsigned>()) .def(pybind11::init<std::string, unsigned, int>()) .def(pybind11::init<std::string, unsigned, int, int>()) .def_readonly("name", &Tank::name) .def_readonly("lives", &Tank::lives) .def_readonly("x", &Tank::x) .def_readonly("y", &Tank::y); } pybind11
  • 30. 29 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <string> #define INITIAL_LIVES 3u struct Tank { std::string name; unsigned lives; int x; int y; Tank(std::string name_, unsigned lives_ = INITIAL_LIVES, int x_ = 0, int y_ = 0) : name{ name_ }, lives{ lives_ }, x{ x_ }, y{ y_ } {} Tank() : Tank("IS") {} bool is_dead() const { return lives == 0u; } };
  • 31. 30 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <pybind11pybind11.h> PYBIND11_MODULE(tank, m) { pybind11::class_<Tank>(m, "Tank") .def(pybind11::init<>()) .def(pybind11::init<std::string>()) .def(pybind11::init<std::string, unsigned>()) .def(pybind11::init<std::string, unsigned, int>()) .def(pybind11::init<std::string, unsigned, int, int>()) .def_readonly("name", &Tank::name) .def_readonly("lives", &Tank::lives) .def_readonly("x", &Tank::x) .def_readonly("y", &Tank::y) .def_property_readonly("is_dead", &Tank::is_dead) } pybind11
  • 32. 31 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <string> #define INITIAL_LIVES 3u struct Tank { std::string name; unsigned lives; int x; int y; Tank(std::string name_, unsigned lives_ = INITIAL_LIVES, int x_ = 0, int y_ = 0) : name{ name_ }, lives{ lives_ }, x{ x_ }, y{ y_ } {} Tank() : Tank("IS") {} bool is_dead() const { return lives == 0u; } std::string to_string() const { return "<" + name + ":" + std::to_string(lives) + " [" + std::to_string(x) + ", " + std::to_string(y) + "]>"; } };
  • 33. 32 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <pybind11pybind11.h> PYBIND11_MODULE(tank, m) { pybind11::class_<Tank>(m, "Tank") .def(pybind11::init<>()) .def(pybind11::init<std::string>()) .def(pybind11::init<std::string, unsigned>()) .def(pybind11::init<std::string, unsigned, int>()) .def(pybind11::init<std::string, unsigned, int, int>()) .def_readonly("name", &Tank::name) .def_readonly("lives", &Tank::lives) .def_readonly("x", &Tank::x) .def_readonly("y", &Tank::y) .def_property_readonly("is_dead", &Tank::is_dead) .def("__repr__", &Tank::to_string); } pybind11
  • 34. 33 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <string> #define INITIAL_LIVES 3u struct Tank { std::string name; unsigned lives; int x; int y; Tank(std::string name_, unsigned lives_ = INITIAL_LIVES, int x_ = 0, int y_ = 0) : name{ name_ }, lives{ lives_ }, x{ x_ }, y{ y_ } {} Tank() : Tank("IS") {} bool is_dead() const { return lives == 0u; } std::string to_string() const { return "<" + name + ":" + std::to_string(lives) + " [" + std::to_string(x) + ", " + std::to_string(y) + "]>"; } }; bool operator==(const Tank& t1, const Tank& t2) { return t1.name == t2.name; }
  • 35. 34 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <pybind11pybind11.h> PYBIND11_MODULE(tank, m) { pybind11::class_<Tank>(m, "Tank") .def(pybind11::init<>()) .def(pybind11::init<std::string>()) .def(pybind11::init<std::string, unsigned>()) .def(pybind11::init<std::string, unsigned, int>()) .def(pybind11::init<std::string, unsigned, int, int>()) .def_readonly("name", &Tank::name) .def_readonly("lives", &Tank::lives) .def_readonly("x", &Tank::x) .def_readonly("y", &Tank::y) .def_property_readonly("is_dead", &Tank::is_dead) .def("__eq__", [](const Tank& l, const Tank& r) { return l == r; }, pybind11::is_operator()) .def("__repr__", &Tank::to_string); } pybind11
  • 36. 35 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE #include <pybind11pybind11.h> #include <pybind11/operators.h> PYBIND11_MODULE(tank, m) { pybind11::class_<Tank>(m, "Tank") .def(pybind11::init<>()) .def(pybind11::init<std::string>()) .def(pybind11::init<std::string, unsigned>()) .def(pybind11::init<std::string, unsigned, int>()) .def(pybind11::init<std::string, unsigned, int, int>()) .def_readonly("name", &Tank::name) .def_readonly("lives", &Tank::lives) .def_readonly("x", &Tank::x) .def_readonly("y", &Tank::y) .def_property_readonly("is_dead", &Tank::is_dead) .def(pybind11::self == pybind11::self) .def("__repr__", &Tank::to_string); } pybind11
  • 37. 36 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE PYBIND11_MODULE(tank, m) { pybind11::class_<Tank>(m, "Tank") ... .def(pybind11::pickle( [](const Tank& t) { /* __getstate__ */ return pybind11::make_tuple(t.name, t.lives, t.x, t.y); }, [](pybind11::tuple t) {/* __setstate__ */ if (t.size() != 4) throw std::runtime_error("Invalid data!"); Tank tank(t[0].cast<std::string>(), t[1].cast<unsigned>(), t[2].cast<int>(), t[3].cast<int>()); return tank; } )); } pybind11
  • 38. 37 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 CLASS EXAMPLE >>> from tank import Tank >>> Tank() <IS:3 [0, 0]> >>> is2 = Tank("IS-2") >>> is2.name 'IS-2' >>> is2.is_dead False >>> is2 == Tank() False python
  • 39. 38 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Docstrings can be set by passing string literals to def(). Arguments can be named via py::arg("..."). m.def("shoot", [](const std::string& name) { pybind11::print("Didn't penetrate the armor of " + name + "."); }, "Shoot a tank.", pybind11::arg("name") );
  • 40. 39 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Docstrings can be set by passing string literals to def(). Arguments can be named via py::arg("..."). m.def("shoot", [](const std::string& name) { pybind11::print("Didn't penetrate the armor of " + name + "."); }, "Shoot a tank.", pybind11::arg("name") ); >>> shoot('IS') Didn't penetrate the armor of IS. >>> help(shoot) Help on built-in function shoot in module tank: shoot(...) shoot(name: unicode) -> None Shoot a tank.
  • 41. 40 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Default arguments. m.def("shoot", [](const std::string& name, unsigned times) { if (times > 3) pybind11::print(“Kill " + name + ".") else pybind11::print("Didn't penetrate " + name + "."); }, "Shoot a tank.", pybind11::arg("name"), pybind11::arg(“times") = 1 );
  • 42. 41 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Default arguments. m.def("shoot", [](const std::string& name, unsigned times) { if (times > 3) pybind11::print(“Kill " + name + ".") else pybind11::print("Didn't penetrate " + name + "."); }, "Shoot a tank.", pybind11::arg("name"), pybind11::arg(“times") = 1 ); >>> shoot("IS") Didn't penetrate IS. >>> shoot("IS-2", 4) Kill IS-2.
  • 43. 42 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Variadic positional and keyword arguments. m.def("count_args", [](pybind11::args a, pybind11::kwargs kw) { pybind11::print(a.size(), "args,", kw.size(), "kwargs"); }); >>> count_args(14, 10, 2017, corehard='autumn') 3 args, 1 kwargs
  • 44. 43 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Python objects as arguments. m.def("count_tanks", [](pybind11::list list) { int n = 0; for (auto item : list) if (pybind11::isinstance<Tank>(item)) ++n; return n; }); >>> from tank import count_tanks >>> count_tanks([Tank("IS-2"), Tank(), 1, "IS-7"]) 2
  • 45. 44 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Function overloading . m.def("go_to", [](int x, int y) { return "go_to int"; }); m.def("go_to", [](double x, double y) { return "go_to double"; }); >>> go_to(25, 4) 'go_to int' >>> go_to(3.14, 3.14) 'go_to double'
  • 46. 45 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Callbacks. int func_arg(const std::function<int(int)> &f) { return f(10); }
  • 47. 46 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Callbacks. int func_arg(const std::function<int(int)> &f) { return f(10); } std::function<int(int)> func_ret(const std::function<int(int)> &f) { return [f](int i) {return f(i) + 1;}; }
  • 48. 47 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Callbacks. int func_arg(const std::function<int(int)> &f) { return f(10); } std::function<int(int)> func_ret(const std::function<int(int)> &f) { return [f](int i) {return f(i) + 1;}; } pybind11::cpp_function func_cpp() { return pybind11::cpp_function( [](int i) { return i + 1; }, pybind11::arg("number") ); }
  • 49. 48 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Callbacks. int func_arg(const std::function<int(int)> &f) { return f(10); } std::function<int(int)> func_ret(const std::function<int(int)> &f) { return [f](int i) {return f(i) + 1;}; } pybind11::cpp_function func_cpp() { return pybind11::cpp_function( [](int i) { return i + 1; }, pybind11::arg("number") ); } #include <pybind11/functional.h> PYBIND11_MODULE(example, m) { m.def("func_arg", &func_arg); m.def("func_ret", &func_ret); m.def("func_cpp", &func_cpp); }
  • 50. 49 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 FUNCTIONS Callbacks. >>> import example >>> def square(i): ... return i * i ... >>> example.func_arg(square) 100L >>> square_plus_1 = example.func_ret(square) >>> square_plus_1(4) 17L >>> plus_1 = func_cpp() >>> plus_1(number=43) 44L
  • 51. 50 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 ENUMS struct Tank { ... enum Type { HEAVY, LIGHT }; }; pybind11::class_<Tank> cls(m, "Tank"); pybind11::enum_<Tank::Type>(cls, "Type") .value(“HEAVY", Tank::Type::HEAVY) .value("LIGHT", Tank::Type::LIGHT) .export_values(); Notes: pybind11 enums are not ints
  • 52. 51 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 EMBEDDING THE INTERPRETER #include <pybind11/embed.h> int main() { pybind11::scoped_interpreter guard{}; // start the interpreter and keep it alive pybind11::exec(R"( kwargs = dict(name="IS", number=667) message = "Shoot {name} with id {number}".format(**kwargs) print(message) )"); }
  • 53. 52 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 EMBEDDING THE INTERPRETER cmake_minimum_required(VERSION 3.0) project(embed_itnterpreter) find_package(pybind11 REQUIRED) # or `add_subdirectory(pybind11)` add_executable(embed_itnterpreter main.cpp) target_link_libraries(embed_itnterpreter PRIVATE pybind11::embed)
  • 54. 53 C++ COREHARD SPRING 2017 IGOR SADCHENKO // C++ COREHARD // 14.10.17 EMBEDDING THE INTERPRETER Importing modules pybind11::module sys = pybind11::module::import("sys"); pybind11::print(sys.attr("path")); Adding embedded modules PYBIND11_EMBEDDED_MODULE(fast_calc, m) { // 'm' is a 'py::module' which is used to bind functions and classes m.def("add", [](int i, int j) { return i + j; }); } auto fast_calc = pybind11::module::import("fast_calc"); auto result = fast_calc.attr("add")(1, 2).cast<int>();
  • 56. 55 C++ COREHARD AUTUMN 2017 // SUMMARY IGOR SADCHENKO // C++ COREHARD // 14.10.17 CONCLUSION pybind11 • simple to use • efficient • supported by the community
  • 57. 56 C++ COREHARD SPRING 2017 // IGOR SADCHENKO // C++ COREHARD // 14.10.17 LINKS python https://www.python.org https://docs.python.org/3/extending/index.html https://docs.python.org/3/c-api/index.html pybind11 https://github.com/pybind/pybind11 http://pybind11.readthedocs.io/en/stable
  • 58. THANK YOU FOR YOUR ATTENTION!
  • 59. IGOR SADCHENKO software developer +375 33 642 92 91 https://www.facebook.com/WargamingMinsk ANY QUESTIONS? igor.sadchenko@gmail.com wargaming.com https://www.linkedin.com/company/wargaming-net