Die Kraft von Pybind11 wird durch das folgende Zitat von Pybind11 von Readme erfasst:
Pybind11 ist eine leichte Bibliothek mit nur Header, die C ++-Typen in Python und umgekehrt enthüllt, hauptsächlich, um Python-Bindungen von vorhandenem C ++-Code zu erstellen. Seine Ziele und Syntax ähneln der hervorragenden Boost.Python -Bibliothek von David Abrahams ...
Das Hauptproblem mit Boost.python - und der Grund für die Erstellung eines ähnlichen Projekts - ist Boost. Boost ist eine enorm große und komplexe Suite von Dienstprogrammbibliotheken, die mit fast jedem existierenden C ++ - Compiler zusammenarbeiten. ... Jetzt, da C ++ 11-kompatible Compiler weit verbreitet sind, ist diese schwere Maschinerie zu einer übermäßig großen und unnötigen Abhängigkeit geworden.
Dieses Repository enthält mehrere Beispiele für die Verwendung von Pybind11. Obwohl die von den Entwicklern von Pybind11 bereitgestellten Online -Dokumentation die Verwendung von IT relativ einfach macht, machen mehrere Beispiele - wie hier angegeben - Pybind11 noch einfacher zu bedienen. Diese Beispiele sind dafür gedacht, dass Sie mit Pybind11 schneller beginnen. Sie sind jedoch keineswegs erschöpfend und bieten nicht immer die optimale Wahl. Daher ist es sehr ratsam, selbst zu denken . Darüber hinaus sind Beiträge mit ähnlichen einfachen Beispielen (oder durch weitere Verbesserung bestehender Beispiele) sehr willkommen . Bitte stellen Sie eine Pull -Anfrage oder ein Problem auf GitHub ein oder kontaktieren Sie mich.
Kredite geben, wo Kredit fällig ist:
Die Schöpfer von Pybind11 haben großartige Arbeit geleistet! Es ist wirklich einfach zu bedienen und sehr leicht. Auch die Dokumentation ist bereits ziemlich vollständig.
Die von Cliburn Chan und Janice McCarthy an der Duke University erhältlichen Beispiele waren enorme Hilfe. Bitte lesen Sie auch ihre Dokumentation.
Beachten Sie, dass es auch Testfälle gibt, die sich als Beispiele im Pybind11 -Repository dienen, diese jedoch nicht sehr aufschlussreich sind, wenn Sie neu in Pybind11 sind.
Schließlich wird Pybind11 aktiv verwendet. So kann man in aktiv gepflegten Bibliotheken nach bestimmten Lösungen suchen. Zum Beispiel:
Das Pybind11 -Modul (nur Header!) Ist als Submodul dieses Repositorys enthalten. Dies erfordert eine gewisse Aufmerksamkeit beim Klonen dieses Projekts. Es gibt zwei Optionen:
Die einfachste Option ist:
git clone --recursive https://github.com/tdegeus/pybind11_examples.gitDadurch wird das Submodule auf die Version, die in diesem Projekt verwendet wird, heruntergeladen. Aktualisieren Sie den neuesten Komitee des Submoduls selbst:
git submodule update --remoteMan könnte das Submodul auch direkt aus der Quelle herunterladen:
git clone https://github.com/tdegeus/pybind11_examples.git
cd pybind11_examples
git submodule init
git submodule updateDie Eigenbibliothek wird in einigen der numpy Beispiele verwendet. Aus diesen Beispielen kann beobachtet werden, dass Eigen und Numpy durch Pybind11 wirklich Handshake -Module sind. Es wird fast kein Code benötigt, um die C ++/Python -Schnittstelle zu erstellen. Beachten Sie, dass der größte Teil der Einfachheit davon abhängt, dass Kopien übergeben werden. Es ist eine gewisse Aufmerksamkeit erforderlich, wenn man nur durch Referenz übergehen möchte.
Eigen braucht keine Installation, da es sich auch nur um Kopfball handelt. Man muss nur die Dateien herunterladen und die Header zum Kompilierzeit eingeben.
Im Allgemeinen kann man Eigen herunterladen und installieren durch:
mkdir /path/to/temp/build
cmake /path/to/eigen/download
make installFür macOS könnte man einfach verwenden
brew install eigen
Danach kompilieren mit
clang++ -I/path/to/eigen/instalation ...Beachten Sie, dass PKG-Config bei ordnungsgemäß konfiguriertem (was normalerweise der Fall ist), um die Pfade im Auge zu behalten:
clang++ ` pkg-config --cflags eigen3 ` ...Oder man kann CMake verwenden (siehe unten).
Wenn Sie eine einfache Bibliothek haben, möchten Sie vielleicht alles selbst tun. In diesem Fall kompilieren Sie Ihre C ++ - Quelle zu einem gemeinsam genutzten Objekt, das mit Python verknüpft ist. Das läuft auf
c++ -O3 -shared -std=gnu++11 -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPIC Pybind11 -Anwendungen können mit CMake sehr einfach zusammengestellt werden. Der Einfachheit halber wird Pybind11 als Unterordner der folgenden Beispiele (in der Tat eine symbolische Verbindung zu über vielen Kopien) enthalten, damit wir einen CMakeLists.txt verwenden können.
cmake_minimum_required ( VERSION 2.8.12)
project (example)
add_subdirectory (pybind11)
pybind11_add_module(example example.cpp) (wobei dieses Beispielmodul aus einem einzelnen Quelldatei example.cpp besteht). Um es zu kompilieren, verwenden Sie:
cd /path/to/build
cmake /path/to/example/src
make Wenn Eigen "installiert" ist, kann es einfach einbezogen werden, indem in CMakeLists.txt Folgendes hinzugefügt wird:
find_package ( PkgConfig )
pkg_check_modules( EIGEN3 REQUIRED eigen3 )
include_directories ( ${EIGEN3_INCLUDE_DIRS} ) Der C ++ 14 -Standard kann verwendet werden, indem die folgenden in CMakeLists.txt einbezogen werden:
set (CMAKE_CXX_STANDARD 14) Eine Datei setup.py kann Ihrer Bibliothek hinzugefügt werden. Sie können dann kompilieren und installieren mithilfe
python3 setup.py build
python3 setup.py install Obwohl das Schreiben der setup.py nicht schwer ist, wird es hier nicht behandelt. Man kann einige in CPPMAT enthaltene Tools verwenden, die mit PIP (z. B. pip3 install cppmat ) installiert werden können. Darüber hinaus können Sie sich das setup.py ansehen.
In diesem Beispiel wird eine Funktion modify , die eine Liste annimmt (schreibgeschützt), alle Einträge mit zwei Einträgen multipliziert und als eine Liste von Doppelbildern zurückgegeben wird (siehe example.cpp ). Aus Python ist diese Funktion in einem einfachen example enthalten (siehe test.py ).
Der Zweck dieses Beispiels besteht darin, zu zeigen, wie eine Funktion eine Liste akzeptiert, wie Sie diese in den Standard C ++ std::vector konvertieren und wie Sie einen neuen std::vector (oder eine Liste) zurückgeben. Beachten Sie, dass der tatsächliche Betrieb nicht sehr wichtig ist, sondern die Schnittstelle, die dargestellt wird.
Um zu kompilieren, verwenden Sie entweder CMake, wobei die Kompilierungsanweisungen von CMakeLists.txt nach anschließend gelesen werden:
cmake .
makeOder direkt mit:
c++ -O3 -shared -std=gnu++11 -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPICFühren Sie das Beispiel von: aus:
python3 test.pyUm mit Python 2 zu laufen, ersetzen Sie einfach die beiden Vorkommen von "Python3" oben durch "Python". Um die CMAKE -Anweisungen zu ändern, finden Sie mehr online.
Wie beim vorherigen Beispiel, aber mit einer verschachtelten Liste.
Eine Funktion modify , die die Einträge von einem eindimensionalen Array in Ganzzahlen umwandelt und diese Einträge dann mit 10 multipliziert.
Der Zweck dieses Beispiels ist es, zu zeigen, wie eine Funktion ein eindimensionales Numpy-Array akzeptiert, wie man diese in den Standard C ++ std::vector umwandelt und wie ein eindimensionales Numpy-Array zurückgibt. Beachten Sie, dass die mit Pybind11 generierte Schnittstelle so flexibel ist, dass sie sogar Listeneingänge auf der Python -Seite akzeptiert.
Eine length . Diese Funktion akzeptiert eine 'Matrix', in der eine Liste von 2-D-Positionsvektoren als Zeilen umfasst. Das Ergebnis ist erneut eine 'Matrix' mit für jede Zeile der Position "X" und "Y" und die Länge des 2-D-Positionsvektors.
Zwei Funktionen det und inv , die die Eigenbibliothek verwenden.
Der Zweck dieses Beispiels ist es, zu zeigen, wie trivial die Wechselwirkung zwischen C ++/Eigen und Python/Numpy ist.
Um mit CMake zu kompilieren und zu laufen, folgen Sie den obigen Anweisungen (wobei die Eigenkopfzeile in CMakeLists.txt enthalten sind.
c++ -O3 -shared -std=gnu++11 -I /path/to/eigen -I ./pybind11/include ` python3-config --cflags --ldflags --libs ` example.cpp -o example.so -fPICZum Beispiel auf MacOS mit Homebrew:
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 Eine benutzerdefinierte CustomVectorXd -Klasse mit einer Funktion mul . Diese Klasse verwendet die Eigenbibliothek. Es enthält auch ein Standardargument.
Darüber hinaus hat dieses Beispiel eine Funktion trans (völlig nichts mit der CustomVectorXd -Klasse). Ziel ist es zu zeigen, wie man ein neues Eigen::VectorXi (oder Numpy-Array) zurückgibt.
Eine überlastete Funktion mul . Diese Funktion wirkt "unterschiedlich", wenn sie mit int -Argumenten oder double Argumenten aufgerufen wird. Beachten Sie, dass das Standardverhalten von Pybind11 ziemlich robust ist. Wenn Sie die Funktion mit einem int und einem double Argument aufrufen, wählt das Modul die double Version von mul aus (und wirft das int -Argument auf ein double ).
Stellen Sie zum Kompilieren sicher, dass der C ++ 14 -Standard verwendet wird, beispielsweise durch Einbeziehung von -std=c++14 als Compiler -Argument.
Ähnlich wie beim vorherigen Beispiel, aber mit Eigenargumenten (dh numpy Argumente aus der Python -Seite).
Stellen Sie sicher, dass der C ++ 14 -Standard verwendet wird.
Dieses Beispiel enthält eine benutzerdefinierte Matrixklasse in C ++ (in matrix.h ). Diese Klasse ist mit einer einfachen Schnittstelle (in pybind_matrix.h ) an ein Numpy-Array gekoppelt. Folglich erfordern die Funktionen (in example.cpp ) keinen speziellen Wrapper -Code.
Siehe auch diese Diskussion über Stack Overflow.
Dieses Beispiel bietet eine Möglichkeit, sich mit einem Enumerator in C ++ zu unterbinden. Grundsätzlich ist die Schnittstelle unkompliziert, rechtfertigt aber einen "Trick". Hier kann ein Submodul in der Lage sein, mit dem Enumerator auf die gleiche Weise wie in C ++ zu interagieren.
Dieses Beispiel enthält ein klassisches Beispiel, bei dem ein oder mehrere Klassen von einem bestimmten Elternteil oder einer bestimmten Vorlage abgeleitet werden. Dieses besondere Beispiel enthält zwei Tiere, einen Dog und eine Cat , die beide aus einer generischen Animal stammen. Es gibt ein talk , das das generische Animal und damit die abgeleiteten Klassen akzeptiert.
Dieser spezielle Fall erfordert eine stärker beteiligte Schnittstelle, wie in der Dokumentation beschrieben.
Dieses Beispiel enthält eine einfache CRTP mit als "Basis" und eine "abgeleitete" Klasse und seine Registrierung an die Pybind11 -API.
Manchmal kann py::overload_cast Ihre Funktion nicht beheben, beispielsweise wenn der Rückgabetyp nicht abgeleitet werden kann. In diesem Fall können Sie durch static_cast einen Zeiger auf Ihre Funktion explizit sein. Weitere Informationen finden Sie in der Dokumentation.