Python/C API - Py_CompileString

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
Pfefferminze
User
Beiträge: 5
Registriert: Donnerstag 24. Februar 2011, 13:49

Hallo ihr lieben,

ich bin gerade dabei Py_CompileString und PyEval_EvalCode zuverwenden. Dabei bin ich auf ein
Problem gestoßen. Und zwar lässt sich mit Py_CompileString nur Zahlen im char vorcompilieren wie "1+2".
Ich würde aber gerne 1. Variablen wie x und y und 2. die mathematischen Cosinus und Sinus verwenden.
Meine Funktion würde dann so aussehen
char = "cos(x) * cos(y)"
Aber leider kennt Py_CompileString weder cosinus noch x oder y.
Gibt es irgendeine Möglichkeit ihm das mitzugeben?
Hoffe auf Hilfe!
Grüße Jessi

Code:

Code: Alles auswählen

PyObject *c = Py_CompileString("cos(x) * cos(y)", "<string>", Py_file_input);
PyObject *r = PyEval_EvalCode((PyCodeObject *)c, dicglobal, diclocal);
BlackJack

@Pfefferminze: Das sollte sich kompilieren lassen. Wie kommst Du darauf dass das nicht geht? Was ist denn der Fehler den Du bekommst. Schaust Du da überhaupt nach?

Ein Problem wird es geben wenn 'cos', 'x', und 'y' beim *ausführen* nicht in ``dicglobal`` und ``diclocal`` auf enstprechende Objekte abgebildet werden. Das zeigst Du ja nicht.

Und dann ist noch die Frage was Du als Rückgabewert erwartest, denn bei `Py_file_input` wird Bytecode erzeugt, der dem Inhalt einer Datei entspricht. Wenn Du 'cos(x) * cos(y)' einfach so in ein Modul speicherst und das ausführst -- ich gehe jetzt mal davon aus das `cos`, `x`, und `y` auf magische Weise global bekannt sind -- dann wird zwar die Rechnung ausgeführt, aber mit dem Ergebnis nichts gemacht. Das wird einfach verworfen.
Pfefferminze
User
Beiträge: 5
Registriert: Donnerstag 24. Februar 2011, 13:49

@BlackJack: Danke für deine Antwort.
ich bekam entweder immer -1 raus nach dem kompilieren, oder er beschwerte sich dass er cos nicht kennt.

Oke, dann änder ich das Py_file_input aufjedenfall mal auf Py_eval_input, müsste ja in meinem Fall das richtige sein.

Wie kann ich denn cos in mein "dicglobal" geben? Ich dachte das includen des math.h würde genügen.
BlackJack

@Pfefferminze: Du willst da *Python*-Code ausführen. Was Du in Deinem *C*-Programm dafür per ``#include`` einbindest ist egal. In einem der beiden Dictionaries muss an den Namen `cos` eine Python-Funktion gebunden werden. Falls das die Berechnung des Kosinus sein soll, dann würde sich sich die `math.cos()`-Funktion anbieten. Du musst also von C aus das `math`-Modul importieren und dort das `cos`-Attribut abfragen, und das dann in eines der beiden Python-Dictionaries unter dem Namen 'cos' ablegen.

Die Werte für `x` und `y` musst Du genau so dort hinein bringen. Den jeweiligen C-Datentyp (wahrscheinlich ``double``) in ein Python-`float` umwandeln und dann unter dem Namen 'x' beziehungsweise 'y' in eines der Dictionary-Objekte stecken.
Pfefferminze
User
Beiträge: 5
Registriert: Donnerstag 24. Februar 2011, 13:49

@BlackJack:

Vielen Vielen Dank. Ich werd das gleichmal Testen.
Schönen Abend noch :D
Antworten