2010-01-30 6 views
5

Ich muss eine vorhandene C++ - Bibliothek für die Verwendung in Python umbrechen. Nach dem Lesen durch this answer on choosing an appropriate method to wrap C++ for use in Python, entschied ich mich, mit Py ++ zu gehen.Verwenden von Code generiert von Py ++ als Python-Erweiterung

Ich ging durch die tutorial for Py++, mit den Tutorial-Dateien, und ich habe die erwartete Ausgabe in generated.cpp, aber ich habe nicht herausgefunden, was zu tun ist, um den generierten Code tatsächlich als Erweiterung zu verwenden, die ich in Python importieren kann . Ich bin mir sicher, dass ich den Code jetzt kompilieren muss, aber womit? Soll ich bjam verwenden?

+0

Schon gesehen? Diese Ankündigung vom Autor von Py ++? http://mail.python.org/pipermail/cplusplus-sig/2009-Januar/014198.html – torial

+0

Ich habe, aber es endet immer noch vor der Beantwortung meiner Frage: "Der letzte Schritt - der Code wird generiert." Ich denke, der letzte Schritt sollte den Benutzer mit Code verlassen, der kompiliert und importiert werden kann, nicht nur generiert. – gotgenes

Antwort

6

Py ++ generiert Ihre Syntax, die Sie zusammen mit boost :: python verwenden, um Python-Einstiegspunkte in Ihrer App zu generieren. Angenommen, alles lief gut mit Py ++, müssen Sie das Boost-Framework herunterladen, und fügen Sie das Boost-Include-Verzeichnis und die Boost :: Python-Lib zu Ihrem Projekt dann mit dem Py ++ generierten cpp kompilieren.

Sie können das für Ihr Projekt gewünschte Build-System verwenden, Boost wird jedoch mit bjam erstellt. Sie müssen wählen, ob Sie eine statische Lib oder eine dynamische Boost-Python-Lib wollen, dann folgen Sie den Anweisungen zum Erstellen von Boost here.

Bei Windows müssen Sie die Erweiterung Ihrer integrierten Bibliothek von .dll in.pyd ändern. Und ja, es muss ein Bibliotheksprojekt sein, das funktioniert nicht mit ausführbaren Dateien.

Dann legen Sie die Pyd, wo der Python auf Ihrem Rechner kann es finden und in Python gehen und Import [Your-Library-Name] und hoffentlich wird alles funktionieren.

Ein letzter Hinweis, der Name in generated.cpp in diesem Makro gegeben:

BOOST_PYTHON_MODULE(-name-) 

muss die genaue Bezeichnung Ihres Projekts sein, sonst wird Python beschweren.

Ich bin gerade erst vor weniger als einem Monat durchgegangen, also weiß ich von der Verwirrung.

Eine Sache, die ich gemacht habe, um meine Python-Erweiterung sehr einfach zu machen, während ich die Bibliothek und das Testen erstelle, war boost :: python und python selbst in meiner Build-Umgebung zu erstellen. Auf diese Weise landet der Pyd genau dort, wo ich ihn haben will und Benutzer müssen Python nicht installieren, um mit meiner Erweiterung zu laufen. Das ist vielleicht zu viel für das, was du tust.

Edit: Wenn Sie möchten, dass Ihre Erweiterung einfach installiert und auf einer Maschine kompiliert werden, überprüfen Sie Pythons setuptools. Mit ein paar einfachen Zeilen können Sie Python kompilieren und Ihr Paket für Sie installieren. Ein Nachteil ist jedoch, dass es nicht IDE-kompatibel für diejenigen von uns ist, die gerne im Visual Studio entwickeln.

3

Die folgende Antwort wurde mir zur Verfügung gestellt von Roman Yakovenko on the Python C++-sig mailing list; Ich poste es hier, mit kleinen Änderungen, zugunsten der Stack Overflow-Community.

Ich verstehe die Antwort noch nicht vollständig, aber ich fühlte, dass es mich in die richtige Richtung weist.


Nachdem Sie den Code generiert haben, müssen Sie ihn kompilieren. Zu diesem Zweck können Sie Ihr bevorzugtes Build-System verwenden. Ich benutze bjam nur um Boost zu kompilieren. Danach bevorzuge ich scons (unter Windows und Linux).

Das folgende ist ein Beispiel für SConstruct-Datei, die eine der Py ++ Unittests zu kompilieren verwendet wird (dieser Code erzeugt wird, auch :-)):

import sys 
env = Environment() 

if 'linux' not in sys.platform: 
    env['MSVS'] = {'VERSION': ''} 
    env['MSVS_VERSION'] = '' 
    Tool('msvc')(env) 

t = env.SharedLibrary(
    target=r'abstract_classes', 
    source=[r'/home/roman/language-binding/sources/pyplusplus_dev/unittests/temp/abstract_classes.cpp'], 
    LIBS=[r"boost_python"], 
    LIBPATH=[r"", r"/home/roman/include/libs"], 
    CPPPATH=[ 
     r"/home/roman/boost_svn", 
     r"/usr/include/python2.6", 
     r"/home/roman/language-binding/sources/pyplusplus_dev/unittests/temp", 
     r"/home/roman/language-binding/sources/pyplusplus_dev/unittests/data", 
     r"/home/roman/boost_svn" 
    ], 
    CCFLAGS=[ ], 
    SHLIBPREFIX='', 
    SHLIBSUFFIX='.so' 
) 

Da Ihr Code-Generator in Python geschrieben, Sie kann fortfahren, wo Py ++ aufhört und Ihre Lieblings- "make" -Datei erzeugt. Du kannst sogar Vater gehen. Py ++ Tests generieren den Code, kompilieren, laden das neue Modul und testen die Funktionalität. All dies geschieht in einem einzigen, unabhängigen Prozess.

1

Ich schrieb eine kleine Make-Datei mit dem folgenden:

GNUmakefile:

PYTHON_INC=$(shell python-config --includes) 
PYTHON_LIBS=$(shell python-config --libs) 
BOOST_LIBS=-lboost_python 

all: 
    g++ -W -Wall $(PYTHON_INC) $(PYTHON_LIBS) $(BOOST_LIBS) -fPIC -shared generated.cpp -o hw.so 

und geladen dann dem .so in ipython erstellt, mit ihm zu spielen, um:

In [1]: import hw 
In [2]: a = hw.animal('zebra') 
In [3]: a.name() 
Out[3]: 'zebra' 
Verwandte Themen