Kommunizieren zwischen python und c ++

Ich möchte ein Python-Modul erstellen, das seine Funktionen aus einer C ++ – Klasse aufrufen und c ++ – Funktionen aus dieser Klasse aufrufen kann

Ich habe auf Boost gesucht, aber es hat keinen Sinn gemacht, es bezieht sich auf eine gemeinsame Bibliothek (die ich habe keine Ahnung, wie zu erstellen) und ich kann nicht den Code, den sie in Beispielen verwenden (es scheint sehr verwirrend)

Hier ist ihr hallo Welt Tutorial ( http://www.boost.org/doc/libs/1_55_0b1/libs/python/doc/tutorial/doc/html/index.html#python.quickstart )

Nach der C / C ++ – Tradition beginnen wir mit der "Hallo, Welt". Eine C ++ – Funktion:

char const* greet() { return "hello, world"; } 

Kann Python ausgesetzt werden, indem er einen Boost.Python-Wrapper schreibt:

 include <boost/python.hpp> BOOST_PYTHON_MODULE(hello_ext) { using namespace boost::python; def("greet", greet); } 

Das ist es. Wir sind fertig. Wir können das jetzt als eine gemeinsame Bibliothek aufbauen. Die daraus resultierende DLL ist nun für Python sichtbar. Hier ist eine Beispiel-Python-Session:

 >>> import hello_ext >>> print hello_ext.greet() hello, world 

Nächster Halt … Aufbau dein Hello World Modul von Anfang bis Ende …

Könnte jemand bitte helfen zu erklären, was getan wird und vor allem, wie python kennt über die C ++ – Datei

2 Solutions collect form web for “Kommunizieren zwischen python und c ++”

Python weiß nicht über die C ++ – Datei, es wird sich nur des Erweiterungsmoduls bewusst sein, das aus der C ++ – Datei kompiliert wird. Dieses Erweiterungsmodul ist eine Objektdatei, die als gemeinsam genutzte Bibliothek bezeichnet wird. Diese Datei hat eine Schnittstelle, die Python aussieht, als ob es ein normales Python-Modul wäre .

Diese Objektdatei existiert nur, nachdem Sie einem Compiler mitgeteilt haben, die C ++ – Datei zu kompilieren und sie mit allen benötigten Bibliotheken zu verknüpfen. Natürlich ist die erste benötigte Bibliothek Boost.Python selbst, die auf dem System verfügbar sein muss, auf dem du kompilierst.

Sie können Python sagen, um die C ++ – Datei für Sie zu kompilieren, damit Sie nicht mit dem Compiler und seinen Bibliotheksflags verwirren müssen. Um dies zu tun, benötigen Sie eine Datei namens setup.py wo Sie die Setuptools-Bibliothek oder die Standard-Distutils verwenden, um festzulegen, wie Ihre anderen Python-Module auf dem System installiert werden sollen. Einer der Schritte für die Installation ist die Kompilierung aller Erweiterungsmodule, genannt die build_ext Phase.

Lassen Sie uns vorstellen, dass Sie die folgenden Verzeichnisse und Dateien haben:

 hello-world/ ├── hello_ext.cpp └── setup.py 

Der Inhalt von setup.py ist:

 from distutils.core import setup from distutils.extension import Extension hello_ext = Extension( 'hello_ext', sources=['hello_ext.cpp'], include_dirs=['/opt/local/include'], libraries=['boost_python-mt'], library_dirs=['/opt/local/lib']) setup( name='hello-world', version='0.1', ext_modules=[hello_ext]) 

Wie Sie sehen können, sagen wir Python gibt es eine Erweiterung, die wir kompilieren wollen, wo die Quelldatei ist und wo die enthaltenen Bibliotheken zu finden sind. Das ist systemabhängig . Das hier gezeigte Beispiel ist für ein Mac OS X-System, bei dem Boost-Bibliotheken über MacPorts installiert wurden.

Der Inhalt von hello_ext.cpp ist wie im Tutorial gezeigt, aber achten Sie darauf, die Dinge neu zu ordnen, damit das Makro BOOST_PYTHON_MODULE nach den Definitionen von was auch immer in Python exportiert werden muss :

 #include <boost/python.hpp> char const* greet() { return "hello, world"; } BOOST_PYTHON_MODULE(hello_ext) { using namespace boost::python; def("greet", greet); } 

Sie können dann sagen, Python zu kompilieren und Link für Sie, indem Sie die folgenden auf der Befehlszeile:

 $ python setup.py build_ext --inplace running build_ext building 'hello_ext' extension /usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -pipe -Os -fwrapv -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/opt/local/include -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c hello_ext.cpp -o build/temp.macosx-10.9-x86_64-2.7/hello_ext.o /usr/bin/clang++ -bundle -undefined dynamic_lookup -L/opt/local/lib -Wl,-headerpad_max_install_names -L/opt/local/lib/db46 build/temp.macosx-10.9-x86_64-2.7/hello_ext.o -L/opt/local/lib -lboost_python-mt -o ./hello_ext.so 

(Die --inplace Flagge teilt Python mit, dass sie die Produkte der Kompilierung direkt neben den Quelldateien hinterlassen. Die Voreinstellung ist, sie in ein build Verzeichnis zu verschieben, um das Quellverzeichnis sauber zu halten.)

Danach finden Sie eine neue Datei namens hello_ext.dll (oder hello_ext.so auf Unix) im hello-world Verzeichnis. Wenn Sie einen Python-Interpreter in diesem Verzeichnis starten, können Sie das Modul hello_ext und den Funktionsgruss verwenden, wie im Boost-Tutorial gezeigt.

Python ist eine interpretierte Sprache. Dies bedeutet, dass es eine virtuelle Maschine benötigt, um die Anweisungen auszuführen. Wenn zum Beispiel a = 5 , python (oder vielmehr die virtuelle Maschine, die Ihren Python-Code interpretiert), wird ein Objekt im Speicher, das einige Informationen und den Wert 5 enthält und wird sicherstellen, dass jeder nachfolgende Hinweis auf a finden wird das Objekt. Gleiches gilt für komplexere Aussagen wie input , bei diesen Befehlen wird die virtuelle Maschine eine hartcodierte Routine auslösen, die eine Menge Arbeit unter der Motorhaube vor der Rückkehr zurück macht, um das nächste Stück des Python-Codes zu lesen. So weit, ist es gut.

Über Module. Wenn Sie die import Anweisung ausgeben, sucht python den angegebenen Modulnamen in seinen Pfad. Dies ist in der Regel eine .py Datei mit nur reinen Python-Code zu interpretieren. Aber das kann auch eine .pyd Datei sein, die kompilierte Routinen enthält, die Python verwenden kann, wie eine ausführbare Datei mit einer gemeinsamen Bibliothek arbeiten würde . Diese Datei enthält Symbole und Einstiegspunkte, so dass, wenn der Dolmetscher einen speziellen Methodennamen wie mymodule.mymethod() , weiß er, wo die Routine zu finden und auszuführen ist.

Allerdings müssen diese Routinen mit einer bestimmten Schnittstelle übereinstimmen, und deshalb ist es nicht einfach, C / C ++ – Funktionen zu python auszusetzen. Das offensichtlichste Problem ist, dass python int ist nicht ein C int , nicht eine short , nicht einmal eine long . Es ist eine spezielle Struktur, die viel mehr Informationen enthält, wie oft die Variable referenziert wird (um Speicher für Variablen freizugeben, die nicht mehr referenziert werden), die Art des Wertes, den es hält usw. Natürlich ist ein typisches C / C ++ – Bibliothek funktioniert nicht mit diesen komplexen Typen, sondern verwendet Vanille int , float , char* und andere schöne einfache Typen. So muss man die notwendigen Python-Werte auf einfache C-Typen übersetzen, die von der Bibliothek verstanden werden können und die von der Bibliothek gelieferten Potenziale in ein von der virtuellen Maschine von python verwendbares Format umwandeln. Das ist die so genannte Wrapper . Der Wrapper muss auch auf lustige Dinge wie Referenzzählungen, Speicherverwaltung auf dem Haufen, Initialisierung und Finalisierung und andere Affen aufpassen. Sehen Sie einige Beispiele , um eine Vorstellung davon zu bekommen, wie dieser Code aussehen kann. Das ist nicht sehr kompliziert, aber immer noch etwas Arbeit.

Jetzt bekommst du eine Vorstellung von all der harten Arbeit, die unter der Kapuze von der Python.Boost Bibliothek (oder anderen Wrapping-Tools für diese Angelegenheiten) beim Aufrufen der lächerlich einfachen def("greet", greet); .

Python ist die beste Programmiersprache der Welt.