C ++ Vektor zu Python 3.3

8

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:

  • Übergeben Sie die Python-Dateinamenszeichenfolge an C ++
  • Erhalte Python-String in C ++
  • FERTIG Erstellen Sie einen Vektor in C ++
  • Rückgabevektor an Python
  • Empfange Vektor in Python
PascalVKooten 22.05.2013, 13:31
quelle

5 Antworten

5

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 ...

  1. 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.

  2. 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.

    
Aya 03.06.2013, 21:20
quelle
6

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 .

    
Dima Tisnek 29.05.2013 20:27
quelle
3

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:

Erweitern von Python mit C ++

Es gibt auch die Möglichkeit, dies über Sockets zu tun, obwohl dies ein bisschen Overkill sein kann, wenn Sie nur Listen durchgehen wollen.

    
Captain Skyhawk 22.05.2013 13:35
quelle
3

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%     
himanshu shekhar 22.05.2013 15:56
quelle
0

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.

    
sissi_luaty 04.06.2013 03:11
quelle

Tags und Links