Ich möchte eine Python-Liste, sagen wir, [1,2,3,4]
, von einem C ++ - Skript erhalten. Ich schrieb das C ++ - Skript, das einen Vektor zurückgibt.
Wie verbinde ich die Enden ohne SWIG / SIP / Cython / und andere?
Könnte es einfacher sein, das C ++ einfach in eine EXE- oder Elf-Datei zu kompilieren und dann von der Befehlszeile aus aufzurufen, die. TXE-Datei mit einem Vektor zu erstellen und sie mit Python einzulesen?
Mein Punkt ist, ich brauche nur eine wirklich kleine Funktion aus C ++, um die schweren Berechnungen mit riesigen Daten durchzuführen. Was wäre die am wenigsten schmerzhafte und kürzeste Methode, um genau dies zu tun?
BEARBEITEN: Um ein Beispiel zu geben. Python gibt C ++ ("foo.txt") eine Dateinamen-Zeichenfolge, die dann den Kontext der Datei liest (200.000 Zeilen mal 300 Spalten), die Missings zählt und dann die Anzahl der fehlenden Zeilen pro Zeile an Python zurücksendet. Dies ergibt eine Liste von 200.000 Nummern. Wie haben wir diese Kommunikation zwischen beiden?
Nur der Vollständigkeit halber frage ich mich noch, wie ich vorgehen soll:
Dies ist wahrscheinlich jetzt moot, und ich postete etwas ähnliches auf Ihre andere Frage , aber ich habe diese Version für Python 3.3 und C ++ anstelle von Python 2.7 und C angepasst.
Wenn Sie ein Python-Listenobjekt zurückbekommen möchten, und da Sie eine Liste erstellen, die möglicherweise sehr lang ist (200.000 Elemente), ist es wahrscheinlich effizienter, die Python-Liste im C ++ - Code zu erstellen und nicht zu erstellen a std::vector
und wandle das später in eine Python-Liste um.
Basierend auf dem Code in Ihrer anderen Frage würde ich vorschlagen, so etwas zu verwenden ...
%Vor%... zusammengestellt mit ...
%Vor%... und ein Anwendungsbeispiel ...
%Vor% ... Wenn Sie eine vorhandene std::vector
in eine Python-Liste konvertieren müssen, können Sie den von der Python-Liste benötigten Speicher vorab reservieren, indem Sie die Länge des Vektors in PyList_New()
, und verwenden Sie dann PyList_SetItem()
anstelle von PyList_Append()
.
Die einzigen anderen Methoden, die ich mir vorstellen kann, wären ...
Um einen RAM-Block in Python vorzubelegen und die C ++ - Funktion zu verwenden, füllen Sie die Werte aus, wie in qarmas Antwort, aber Sie müssen im Voraus wissen, wie viel RAM zuzuweisen ist. Sie könnten einfach einen beliebigen Wert wählen, aber da die Anzahl der Zeilen in der Datei nicht im Voraus bekannt ist, kann diese Zahl viel zu groß oder viel zu klein sein.
Um die std::vector
in C ++ zu heap-allozieren und einen Zeiger auf das erste Element und die Anzahl der Elemente zurückzugeben, aber Sie müssten eine zweite Funktion schreiben, um den RAM freizugeben, sobald Sie fertig sind damit.
Wie auch immer, Sie haben immer noch den Aufwand, das 'zurückgegebene' Array in eine Python-Liste umzuwandeln, also können Sie es auch selbst tun.
Definieren Sie Ihren Einstiegspunkt extern "C"
und verwenden Sie ctypes
.
Hier ist ein Beispiel, um loszulegen, Daten werden von Python übergeben, C ++ - Code sortiert die Daten und Python holt das Ergebnis zurück:
%Vor%Kompilieren Sie Ihren Code in ein gemeinsames Objekt (libxxx.so unter linux, libxxx.dll in win, libxxx.dylib in osx), laden Sie ihn dann dynamisch und übergeben Sie Daten über ctypes:
%Vor% Großartig an ctypes
ist, dass es seit 2.5 mit Python ausgeliefert wird, Sie benötigen keine zusätzlichen Bibliotheken.
Wenn Sie etwas fortgeschritteneres verwenden möchten, werfen Sie einen Blick auf cffi
.
Sie sind auf dem richtigen Weg.
Haben Sie zwei ausführbare Dateien?
Besser wäre es, es in einer Zwischendatei zu speichern. Sperren Sie die Datei, schreiben Sie aus Ihrem C ++ - Code darauf. Entsperren und lesen Sie es von Python.
Wenn Sie nur von Python ausführen möchten, können Sie immer in Python erweitern:
Es gibt auch die Möglichkeit, dies über Sockets zu tun, obwohl dies ein bisschen Overkill sein kann, wenn Sie nur Listen durchgehen wollen.
Sie können das Subprozessmodul in Python verwenden, um die Ausgabe Ihrer C ++ - EXE-Datei zu lesen. Zum Beispiel:
C ++ Datei:
%Vor%Dann ist Ihr Python-Skript:
%Vor%Sie können in der Interprozesskommunikation mit Strings arbeiten: Verwenden Sie die Funktion subprocess.check_output () in Python, um die Ausgabe des C ++ - Programms zu überprüfen und übergeben Sie den Dateinamen als Argument:
Pythons Code:
%Vor%C ++ - Code:
%Vor%EDIT: um die Timer hinzuzufügen und "ast.literal_eval ()" durch "eval ()" zu ersetzen, weil in der Tat eval () in diesem Fall schneller ist und mit python kompatibel ist 3.3.