Frage zu Embedded python mittels C++

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
NoRulez
User
Beiträge: 36
Registriert: Donnerstag 1. November 2007, 15:31

Montag 25. Februar 2008, 16:24

Hey @all,

ich hätte da mal eine Frage, und zwar angenommen mein Python Script sieht wie folgt aus:

Code: Alles auswählen

IN = ()
OUT = ()

def multiply(a,b):
    return a*b

def main():
    OUT = multiply(2, 3), 4, 840, 7*10, 9/3
    print OUT

if __name__ == "__main__":
    main()
Das Grundgerüst soll also so sein das IN und OUT immer da sein sollen bei jedem Script und die main-funktion...
Wie schaffe ich es in C++ das ich auf die IN und OUT tuples/listen zugreifen kann.
Hatte da irgendwie an sowas gedacht wie
void *ptr = //irgendwas von python ("OUT")

Oder löst man sowas anders?

Wäre für jeden Tip sehr dankbar.
Vielen Dank im Voraus und LG
NoRulez
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Montag 25. Februar 2008, 16:41

Möchtest Du "echtes" Embedding praktizieren? Oder willst Du ein bestehendes C++-Programm mit Python kommunizieren lassen?
NoRulez
User
Beiträge: 36
Registriert: Donnerstag 1. November 2007, 15:31

Montag 25. Februar 2008, 16:46

Ich wollte ein C++ Programm, das ich um beliebige Python scripts erweitern kann. Nur müsste ich die IN bzw. OUT Variablen hin und herschieben können.

Lg NoRulez
BlackJack

Montag 25. Februar 2008, 16:49

@NoRulez: Erst einmal ist das `OUT` in der `main()` ein *lokaler* Name. Die Zuweisung hat also keinen Einfluss auf das `OUT` auf Modulebene.

Der übliche Weg, egal ob nun "embedded" oder nicht, ist das Übergeben von Argumenten und Rückgabe von Ergebnissen per ``return`` und keine Kommunikation über globale Variablen. Das sollte eigentlich auch für sauberen C++-Code gelten.
NoRulez
User
Beiträge: 36
Registriert: Donnerstag 1. November 2007, 15:31

Montag 25. Februar 2008, 16:52

Die Sache mit IN und OUT wäre für meine Bedürfnisse aber flexibler, da mich die Funktionen und Klassen im Script nicht wirklich interessieren.

Ich will von C -> Python in IN meine Übergaben machen und mit IN von Python -> C weiterarbeiten.

Dachte man kann irgendwie einen Pointer auf das globale IN und OUT in C++ definieren

Im Endeffekt soll rauskommen das Daten ins Python Script gelangen (IN), danach irgendwas vom Python erledigt wird und ich die Retourwerte ins OUT schreibe, somit ich dann die OUT Werte im C++ weiterverarbeiten kann.
BlackJack

Montag 25. Februar 2008, 17:12

Du musst im Python-Skript ja irgend etwas von C++ aus aufrufen. Da kannst Du doch dann die Argumente übergeben und die Rückgabe wieder entgegennehmen.

Ansonsten sollte das was Du willst, möglich sein, und zwar im Grunde genau so, wie das auch unter Python gehen würde: Mit `setattr()`/`getattr()` auf dem Modul-Objekt, bzw. den entsprechenden Funktionen der C-API.

Wie man in Python das `OUT` von einer Funktion aus setzen würde, darfst Du aber selbst heraus finden. Das ist mir zu hässlich und unsauber um's zu verraten. :P

Eventuell lohnt sich ja auch ein Blick auf Bibliotheken wie boost::python.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Montag 25. Februar 2008, 17:58

NoRulez hat geschrieben:Ich will von C -> Python in IN meine Übergaben machen und mit IN von Python -> C weiterarbeiten.
Danach hatte der erste Beitrag auch irgendwie "gerochen" ;-). Das ginge so ähnlich durchaus über sockets, wenn Du Dir einen Container bastelts. Aber das ist nur die zweitbeste Lösung.

Ansonsten kann ich wieder mal BJ nur beipflichten und neben boost nur SWIG einwerfen. Das würde Dir das Leben ggf. auch viel (!) einfacher machen.

Gruß,
Christian
NoRulez
User
Beiträge: 36
Registriert: Donnerstag 1. November 2007, 15:31

Montag 25. Februar 2008, 18:03

@BlackJack, ich glaube ich drücke mich für das was ich will etwas komisch aus, bzw. kommt dennoch ein missverständniss zu stande.
ich versuche es mal mit ASCII-Art zu zeigen ;-):

Also in c++ habe ich irgendwo eine Funktion die heißt "startPy(module)"
Davor (jedoch weiß ich noch nicht wie) definiere ich mir die "IN Variable" Beispielsweise kommt in die IN 2 und 3 also laut python müsste das dann so aussehen:

Code: Alles auswählen

IN = (2,3)
gut, dann wird irgendwas in dem python script gemacht (multiplizieren, addieren, was weiß ich....zum schluss schreibt python was in OUT. Sagen wir es hat multipliziert, dann würde in OUT folgendes stehen:

Code: Alles auswählen

OUT = (6)
und nun kehrt auch schon wieder die c++ funktion zurück und gibt mir ins c++ programm die Zahl 6 zurück.

Code: Alles auswählen

+---------+     +---------+      
|         |     |         |      
|   C++   | --> | Python  | ---+
|         |     |         |    |
+---------+     +---------+    |
       ^                       |
       |                       |
       |                       |
       +-----------------------+
Das C++ Programm kümmert sich somit um keine Klassen, Funktionen und sonstwas in Python, das soll der Interpreter machen, mir geht es nur darum das ich danach die zahl 6 zurückbekommen.

Natürlich ist "6" Nur ein Beispiel, kann beliebige werte zurückliefern.

Und da dachte ich mir nun das ich in c++ einen Pointer auf IN und einen Pointer auf OUT zeigen lassen kann.

Lg NoRulez


P.S.: Ein Beispiel dazu wäre ein simpler POP3 Client. Ich liefere in IN folgendes:

Code: Alles auswählen

IN = ('pop.server.org', '110', 'USERNAME', 'PASSWORD')
und das Script liefert einfach nur zurück entweder falls keine neuen Emails vorhanden sind:

Code: Alles auswählen

OUT = (false)
oder falls welche vorhanden sind folgendes:

Code: Alles auswählen

OUT = ('FROM', 'DATE', 'SUBJECT', 'TO', 'MESSAGE')
bzw.

Code: Alles auswählen

OUT = (('FROM', 'DATE', 'SUBJECT', 'TO', 'MESSAGE'), ('FROM', 'DATE', 'SUBJECT', 'TO', 'MESSAGE'), ....) 
und ich könnte in C++ gemütlich die Werte abarbeiten, anzeigen oder sontwas mit ihnen tun. Das ganze war jetzt nur ein Beispiel


Ich weiß eben nur nicht wie ich auf IN bzw. auf OUT in C++ zugreife.
Zuletzt geändert von NoRulez am Montag 25. Februar 2008, 18:10, insgesamt 2-mal geändert.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Montag 25. Februar 2008, 18:08

PS Kennst Du Programmin Python? Will keine Werbung machen, aber schau mal in das entsprechende Kapitel rein und denn kannst Du Dich ja entscheiden.
NoRulez
User
Beiträge: 36
Registriert: Donnerstag 1. November 2007, 15:31

Montag 25. Februar 2008, 18:15

CM hat geschrieben:PS Kennst Du Programmin Python? Will keine Werbung machen, aber schau mal in das entsprechende Kapitel rein und denn kannst Du Dich ja entscheiden.
Ist das ein Buch oder ne Webseite? Grundlegend benötige ich ja keine Bücher. Bücher bez. C++ und Python habe ich genug, mir geht es vielmehr um Embedded Python bzw. die Schnittstelle zwischen Python und C++ und diesbezüglich habe ich leider noch keine Bücher gefunden.

Lg NoRulez
BlackJack

Montag 25. Februar 2008, 18:26

@NoRulez: Ich habe schon richtig verstanden was Du willst. Du musst aber in dem Python-Modul letztendlich eine Funktion aufrufen, weil ja irgend etwas ausgeführt werden muss. Und da kannst Du die Kommunikation auch gleich ganz normal über die Argumente und den Rückgabewert der Funktion erledigen. Pointer bekommst Du auf PyObject-Strukturen und musst auch solche übergeben. In beiden Fällen.

Hast Du das Tutorial und die Python/C-API Referenz in der Doku überhaupt schon mal gelesen?
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Montag 25. Februar 2008, 18:33

@NoRulez: Ein Buch. Einfach zu finden, korrekte Rechtschreibung vorausgesetzt :oops:
NoRulez
User
Beiträge: 36
Registriert: Donnerstag 1. November 2007, 15:31

Dienstag 26. Februar 2008, 11:08

@CM: Ich habe statt "Programming Python" schon das Buch "Python Cookbook", wo Extension und embedded angehaucht wird.

Ich frage mich warum das Thema embedded heutzutage nur angehaucht wird, obwohl ich auch in unserer Firma merke das Dynamisierung immer wichtiger wird anstelle von geschwindigkeit.
Da sowieso die Server schon mehr als 2 GB Ram haben und >= 3 GHz haben. :-(
Ansonsten habe ich kein Buch bei Amazon bez. Embedded Python gefunden

Lg NoRulez

Bin Trotzdem noch sehr dankbar falls mir noch jemand einen Tip geben könnte, werde ja wohl nicht der einzige diesbezüglich sein *hoff* ;-)
Lufia
User
Beiträge: 83
Registriert: Samstag 13. Mai 2006, 10:04
Wohnort: Berlin

Mittwoch 27. Februar 2008, 10:46

Es gitb leider wirkllich nicht viel zu dem Thema, die bereits angegebenen Links sind eigentlich echt nicht schlecht. Was fehlt ist eine Art Kochbuch dazu,...

Also ich habe nutze Python von C aus, das Problem ist eigenltich nur die Datentypen umzuwandeln, bzw. zurückzuwandeln. Ich baue mir hierzu extra C-Funktionen welche die Werte für Python umwandlen, Python ausführen und die Resultate wieder zurückwandeln. Es ist eigentlich nicht so wild, hat aber ein paar tücken. Vor allem beim zurückwandeln, und Speicherverwaltung es ist nicht wirklich schön gelößt. Beim zurückwandeln der Resultate und beim Löschen passieren Laien wie mir leicht Fehler (Manche Dinge sind einfach unlogisch). Leider ist der Code auch nicht richtig debugbar.

Da du C++ verwendest würde ich XML-RPC verwenden. Bei mir unter C hatte ich Probleme mit der C XML-RPC libary, die war zickig wenn ich mehrer Aufrufe gemacht habe,..
Ich ruf jetzt mit Embedded-Python Pythonprogramme auf, und sende von dort Werte an eine XML-RPC Server bzw. rufe dessen Funktionen auf. Dann kann man die Sache auch von der Python-Seite aus debuggen und kommt Fehlern schnell auf die Schliche solange sie nciht an C und den Pointern hängen ,-)

Die Performance ist bei mir völlig ausreichend, es kommt halt darauf an was du genau machen möchtest. Aber für dein Email Beispiel sehe ich keine Performanceprobleme.

Also ich würde C++ --> xML-RPC --> Pyhton verwenden.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 27. Februar 2008, 11:12

Hallo NoRulez!

Du kannst mit C++ ein Kommandozeilenprogramm wie z.B. "dir" aufrufen, diesem Kommandozeilenparameter mitgeben und die Rückgabe dieses Programms verwenden.

Genau so kannst du auch ein Python-Programm aufrufen, diesem Kommandozeilenparameter mitgeben und die Rückgabe dieses Python-Programms verwenden.

Das hat natürlich einen Nachteil. Es ist nicht sonderlich schnell, den Interpreter bei jedem Aufruf neu starten zu müssen. Aber zum Versenden von Emails ideal, da absolut einfach.

Wenn es etwas schneller sein soll, könntest du beim Starten deines Programmes auch ein Python-Programm starten und als XMLRPC-Server auf Anfragen warten lassen. Die Python-Seite hierfür ist auch sehr einfach. Wie ein XMLRPC-Aufruf in C++ aussieht, weiß ich nicht. Beim Beenden deines Programmes, lässt du das Python-Programm ebenfalls beenden.

Das Übergeben der Daten vom C++-Programm zum Python-Programm und zurück kann aber auch beschleunigt/verkompliziert werden. Unter Linux kannst du FIFOs dafür verwenden. Unter Windows gibt es NamedPipes. Aber das rentiert sich erst, wenn es auf Geschwindigkeit mit *großen* Datenmengen ankommt.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten