Exposing C++ with Pybind11¶
This guide on exposing C++
using pybind11
is centered around the
architecture of the tudatpy/kernel
source directory. This is done in
order to provider developers with a practical guide that introduces the
implementation and design of the current architecture.
Note
This also allows developers to see motivations for the current design, should convention change, or deprecation of classes/functions occur.
The entirety of exposed C++ functionality in tudatpy
is contained within
the tudatpy/kernel
source directory. For reference during this guide, the
architecture of this directory is as follows:
1 |
|
Module Definition¶
The following folded code shows the core elements of the
level kernel
module definition in tudatpy
. It would serve the reader to
have glance through before we walk through the elements in detail.
tudatpy/kernel/kernel.cpp
¶1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | // expose tudat versioning
#include <tudat/config.hpp>
// include all exposition headers
#include "expose_simulation.h"
// other submodule headers...
// standard pybind11 usage
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(kernel, m) {
// Disable automatic function signatures in the docs.
// NOTE: the 'options' object needs to stay alive
// throughout the whole definition of the module.
py::options options;
options.disable_function_signatures();
options.enable_user_defined_docstrings();
// export the tudat version.
m.attr("_tudat_version_major") = TUDAT_VERSION_MAJOR;
m.attr("_tudat_version_minor") = TUDAT_VERSION_MINOR;
m.attr("_tudat_version_patch") = TUDAT_VERSION_PATCH;
// simulation module definition
auto simulation = m.def_submodule("simulation");
tudatpy::expose_simulation(simulation);
// other submodule definitions...
// versioning of kernel module
#ifdef VERSION_INFO
m.attr("__version__") = VERSION_INFO;
#else
m.attr("__version__") = "dev";
#endif
}
|
Note
Starting with the end in mind, compiling the previous will result in a
shared library named kernel.so
.
Note
With the kernel.so
library added to the Python path variable, users
can then execute ``from kernel import simulation` successfully.
Warning
The Python interpreter searches the sys.path
in its order. Inspect
the sys.path
list to determine which variant of a module is imported.
Submodule Definition¶
tudatpy/kernel/expose_simulation.hpp
¶1 2 3 4 5 6 7 | namespace tudatpy {
void expose_simulation(py::module &m) {
}
}
|
tudatpy/kernel/expose_simulation.cpp
¶1 2 3 4 5 6 7 | namespace tudatpy {
void expose_simulation(py::module &m) {
}
}
|
Class Definition¶
This section walks through the process of exposing C++ classes into Python using Pybind11. An accompanying example is used and extended to certain situations that may be encountered.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Animal {
public:
virtual ~Animal() { }
virtual std::string go(int n_times) = 0;
};
class Dog : public Animal {
public:
std::string go(int n_times) override {
std::string result;
for (int i=0; i<n_times; ++i)
result += "woof! ";
return result;
}
};
|
With Inheritance¶
Containing
Satisfying Conversions¶
STL Containers¶
The following conversion table for STL
containers in C++ can be satisfied
by adding #include <pybind11/stl.h>
to your header file while using
Pybind11 [source_].
Python |
C++ |
|
|
|
|
|
|
NumPy and Eigen¶
The following conversion table for STL
containers in C++ can be satisfied
by adding #include <pybind11/stl.h>
to your header file while using
Pybind11 [source_].
Python |
C++ |
|
|
|
|
|
|
Common Errors Encountered¶
Relating to Eigen¶
1 | python: /home/ggarrett/miniconda3/envs/tudat-env/include/eigen3/Eigen/src/Core/DenseStorage.h:109: Eigen::internal::plain_array<T, Size, MatrixOrArrayOptions, 16>::plain_array() [with T = double; int Size = 6; int MatrixOrArrayOptions = 0]: Assertion `(internal::UIntPtr(eigen_unaligned_array_assert_workaround_gcc47(array)) & (15)) == 0 && "this assertion is explained here: " "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" " **** READ THIS WEB PAGE !!! ****"' failed.
|
Please see Missing Standard Conversions
Missing Conversions¶
Tip
For dealing with conversions between Python lists, NumPy ndarrays and Eigen arrays in C++, the following lines cover all bases. .. code-block:: cpp
- linenos
// Conversion for standard types (e.g. list->vector) #include <pybind11/stl.h> // Limited conversion for numpy<->eigen #include <pybind11/eigen.h> #include <pybind11/numpy.h>