El poder de Pybind11 es capturado por la siguiente cita del Readme de Pybind11:
Pybind11 es una biblioteca liviana solo de encabezado que expone los tipos de C ++ en Python y viceversa, principalmente para crear enlaces de Python del código C ++ existente. Sus objetivos y sintaxis son similares a la excelente biblioteca Boost.python de David Abrahams ...
El problema principal con Boost.python, y la razón para crear un proyecto tan similar, es Boost. Boost es un conjunto enormemente grande y complejo de bibliotecas de utilidad que funciona con casi todos los compiladores de C ++ que existen. ... Ahora que los compiladores compatibles con C ++ 11 están ampliamente disponibles, esta maquinaria pesada se ha convertido en una dependencia excesivamente grande e innecesaria.
Este repositorio contiene varios ejemplos para el uso de Pybind11. A pesar de que la documentación en línea proporcionada por los desarrolladores de Pybind11 hace que el uso de TI sea relativamente sencillo, varios ejemplos, como se proporcionan aquí, hacen que Pybind11 sea aún más fácil de usar. Estos ejemplos están destinados a comenzar más rápido con Pybind11. Sin embargo, no son exhaustivos, y no siempre proporcionan la opción óptima. Por lo tanto, es muy aconsejable pensar por sí mismo . Además, las contribuciones con ejemplos simples similares (o mejorando aún más los ejemplos existentes) son muy bienvenidas . POR FAVOR POR FAVOR UNA solicitud de extracción o un problema en GitHub, o contácteme.
Para dar crédito donde se debe:
¡Los creadores de Pybind11 han hecho un gran trabajo! Es realmente fácil de usar y muy liviano. Además, la documentación ya está bastante completa.
Los ejemplos disponibles por Cliburn Chan y Janice McCarthy, en la Universidad de Duke, han sido de gran ayuda. Por favor, lea también su documentación.
Tenga en cuenta que también hay casos de prueba que se duplican como ejemplos en el repositorio de Pybind11, pero estos no son muy perspicaces cuando es nuevo en Pybind11.
Finalmente, Pybind11 se usa activamente. Entonces uno puede buscar en bibliotecas mantenidas activamente para soluciones específicas. Por ejemplo:
El módulo pybind11 (¡que es solo encabezado!) Se incluye como un submódulo de este repositorio. Esto requiere cierta atención al clonar este proyecto. Hay dos opciones:
La opción más simple es:
git clone --recursive https://github.com/tdegeus/pybind11_examples.gitEsto descargará el submódulo a la versión que se utiliza en este proyecto. Para actualizar la última confirmación del submódulo en sí:
git submodule update --remoteTambién se podría descargar directamente el submódulo de la fuente:
git clone https://github.com/tdegeus/pybind11_examples.git
cd pybind11_examples
git submodule init
git submodule updateLa biblioteca Eigen se usa en algunos de los ejemplos numpy. A partir de estos ejemplos, se puede observar que a través de Pybind11, Eigen y Numpy son realmente módulos de apretón de manos. Casi no se necesita código para crear la interfaz C ++/Python. Tenga en cuenta que la mayor parte de la simplicidad depende de las copias que se pasan, se necesita atención si uno quiere aprobar puramente por referencia.
Eigen no necesita instalación porque también es solo encabezado. Uno solo necesita descargar los archivos e incluir los encabezados en el momento de la compilación.
En general, uno puede descargar e instalar el eigen por:
mkdir /path/to/temp/build
cmake /path/to/eigen/download
make installPara macOS se podría usar simplemente
brew install eigen
A partir de entonces compilar con
clang++ -I/path/to/eigen/instalation ...Tenga en cuenta que, cuando está configurado correctamente (que normalmente es el caso), PKG-Config se puede usar para realizar un seguimiento de las rutas:
clang++ ` pkg-config --cflags eigen3 ` ...O uno puede usar cmake (ver más abajo).
Si tiene una biblioteca simple, es posible que desee hacer todo usted mismo. En este caso, compila su fuente de C ++ a un objeto compartido que está vinculado a Python. Esto se reduce a
c++ -O3 -shared -std=gnu++11 -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPIC Las aplicaciones Pybind11 se pueden compilar muy fácilmente usando CMake. Por simplicidad, Pybind11 se incluye como un subcarpeta de los ejemplos a continuación (de hecho, utilizando un enlace simbólico a más de muchas copias), para que podamos usar una CMakeLists.txt como:
cmake_minimum_required ( VERSION 2.8.12)
project (example)
add_subdirectory (pybind11)
pybind11_add_module(example example.cpp) (por el cual este módulo de ejemplo consiste en un solo archivo fuente, example.cpp ). Para compilarlo, usar:
cd /path/to/build
cmake /path/to/example/src
make Cuando Eigen está 'instalado', se puede incluir fácilmente agregando lo siguiente en CMakeLists.txt :
find_package ( PkgConfig )
pkg_check_modules( EIGEN3 REQUIRED eigen3 )
include_directories ( ${EIGEN3_INCLUDE_DIRS} ) El estándar C ++ 14 se puede usar incluyendo lo siguiente en CMakeLists.txt :
set (CMAKE_CXX_STANDARD 14) Se puede agregar un archivo setup.py a su biblioteca. Luego puede compilar e instalar usando
python3 setup.py build
python3 setup.py install Aunque escribir el setup.py no es difícil, no está cubierto aquí. Uno puede usar algunas herramientas incluidas en CPPMAT, que se pueden instalar con PIP (por ejemplo, pip3 install cppmat ). Además, puede ver el setup.py , por ejemplo, goosetensor o varios de mis repositorios.
Este ejemplo presenta una función modify que toma una lista (de solo lectura), multiplica todas las entradas por dos y la devuelve como una lista de dobles (ver example.cpp ). Desde Python, esta función está contenida en un example de módulo simple (ver test.py ).
El propósito de este ejemplo es mostrar cómo hacer que una función acepte una lista, cómo convertir esto en el std::vector y cómo devolver un nuevo std::vector (o lista). Tenga en cuenta que la operación real no es muy importante, es la interfaz que se ilustra.
Para compilar, emplee CMake, mediante el cual las instrucciones de compilación se leen de CMakeLists.txt por posteriormente:
cmake .
makeO, compilar directamente usando:
c++ -O3 -shared -std=gnu++11 -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPICEjecute el ejemplo por:
python3 test.pyPara correr con Python 2, simplemente reemplace las dos ocurrencias de "Python3" arriba con "Python". Para modificar las instrucciones de CMake, encuentre más en línea.
Igual que el ejemplo anterior, pero con una lista anidada.
Una función modify que convierte las entradas de una matriz unidimensional a enteros, y luego multiplica estas entradas por 10.
El propósito de este ejemplo es mostrar cómo hacer una función que acepte una matriz numpy unidimensional, cómo convertir esto en el std::vector y cómo devolver una matriz numpy unidimensional. Tenga en cuenta que la interfaz generada con Pybind11 es tan flexible que incluso acepta las entradas de la lista en el lado de Python.
Una length de función. Esta función acepta una 'matriz' en la que comprende una lista de vectores de posición 2-D, como filas. El resultado es nuevamente una 'matriz' con cada fila la posición "x" e "y", y la longitud del vector de posición 2-D.
Dos funciones det e inv que usan la biblioteca Eigen.
El propósito de este ejemplo es mostrar cuán trivial es la interacción entre C ++/Eigen y Python/Numpy.
Para compilar el uso de CMake y ejecutar, siga las instrucciones anteriores (por las cuales los encabezados Eigen se incluyen en CMakeLists.txt . Para compilar directamente, además deben incluirse los encabezados de Eigen:
c++ -O3 -shared -std=gnu++11 -I /path/to/eigen -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPICPor ejemplo, en macOS con cerveza casera:
c++ -O3 -shared -std=gnu++11 -I /usr/local/Cellar/eigen/3.3.1/include/eigen3 -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPIC Una clase personalizada CustomVectorXd con una función mul . Esta clase usa la biblioteca Eigen. También incluye un argumento predeterminado.
Además, este ejemplo tiene una función trans (totalmente no relacionada con la clase personalizada CustomVectorXd ). Su propósito es mostrar cómo devolver un nuevo Eigen::VectorXi (o matriz numpy).
Una función sobrecargada mul . Esta función actúa "de manera diferente" si se llama con argumentos int o argumentos double . Observe que el comportamiento predeterminado de Pybind11 es bastante robusto. Al llamar a la función con un int y un argumento double , el módulo elegirá la versión double de mul (y lanzará el argumento int a un double ).
Para compilar, asegúrese de que se use el estándar C ++ 14, por ejemplo, incluyendo -std=c++14 como argumento del compilador.
Similar al ejemplo anterior, pero con argumentos propios (es decir, argumentos numpy del lado de Python).
Para compilar, asegúrese de que se use el estándar C ++ 14.
Este ejemplo incluye una clase de matriz personalizada en C ++ (en matrix.h ). Esta clase está acoplada a una matriz numpy utilizando una interfaz simple (en pybind_matrix.h ). En consecuencia, las funciones (en example.cpp ) no requieren ningún código de envoltura especial.
Vea también esta discusión sobre el desbordamiento de la pila.
Este ejemplo presenta una forma de interactuar con un enumerador en C ++. En principio, la interfaz es directa pero garantiza un "truco". Aquí se utiliza un submódulo para poder interactuar con el enumerador de la misma manera que en C ++.
Este ejemplo contiene un ejemplo clásico en el que una o más clases se derivan de un determinado padre o plantilla. Este ejemplo particular contiene dos animales, un Dog y un Cat , que se derivan de una clase Animal genéricos. Hay una talk de función que acepta el Animal genérico y, por lo tanto, cualquiera de las clases derivadas.
Este caso particular requiere una interfaz más involucrada, como se describe en la documentación.
Este ejemplo presenta un CRTP simple con la clase 'base' y 'derivada', y su registro en la API Pybind11 .
A veces, py::overload_cast no puede resolver su función, por ejemplo, cuando no se puede inferir el tipo de retorno. En ese caso, puede ser explícito mediante static_cast un puntero a su función que se puede encontrar más información en la documentación.