[C/C++] PyRun_String

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Samstag 29. Mai 2010, 13:07

Ich versuche gerade eine Script-Engine zu programmieren, die auf Python basiert. Leider hat der Python-Interpreter ein Problem mit dem Script (als Beispiel):

Code: Alles auswählen

def event20x18():
    print "Hallo Welt"

def run_event(x,y):
    if (globals().has_key("event%dx%d"%(x,y))): exec "event%dx%d()"%(x,y)
Egal was ich in die erste Zeile des Scripts schreibe (import, def, print etc.), der Intepreter meldet mir immer einen SyntaxError:

Code: Alles auswählen

 File "", line 1
def event20x18():
          ^
SyntaxError: invalid syntax
Das Script wird mit Hilfe von PyRun_String ausgeführt:

Code: Alles auswählen

// 'main_dict' ist ein Python-Dict (PyObject*) mit den Globalen Variablen des Scripts
// 'data' ist ein std::string mit dem Code

	PyRun_String(data.c_str(), Py_single_input,  main_dict, main_dict);
Danke schonmal im Voraus...
~Birne
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Samstag 29. Mai 2010, 13:14

http://docs.python.org/c-api/intro.html ... ing-python
http://docs.python.org/extending/embedding.html

Besonders der zweite Link erklärt alles was du brauchst. PyRun_String ist eher für kleine Sachen gedacht. Ganze Module sollte man ordentlich laden & importieren.

Gruß
Grüßle.
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Samstag 29. Mai 2010, 13:53

ok, danke erstmal für den Tipp.
Ich habe die entsprechenden Zeilen jetzt so geändert (data ist ein std::string):

Code: Alles auswählen

	PyObject* pModuleCode = Py_CompileString(data.c_str(), "map.py", Py_file_input);
	if (! pModuleCode) TB_ERROR_NULL_POINTER("pModuleCode", TB_ERROR);

	PyObject* pModule = PyImport_ExecCodeModule("mapscript", pModuleCode);
	if (! pModule) TB_ERROR_NULL_POINTER("pModule", TB_ERROR);
Jedoch ist pModuleCode immer NULL (egal ob der Code jetzt aus print "Hallo Welt" oder komplexerem besteht)...

Hast du eine Idee, woran das liegen könnte?

~Birne

PS: Das Makro TB_ERROR_NULL_POINTER gibt nur eine Fehlermeldung aus...
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Samstag 29. Mai 2010, 13:56

Hi.
Wieso verwendest du nicht erstmal PyImport_Import zum testen? Hast du auch den Suchpfad angepasst, so, dass deine Dateien gefunden werden können?

Gruß
Grüßle.
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Samstag 29. Mai 2010, 13:59

Das Problem ist, dass die Scripte, die ausgeführt werden sollen, aus einem Speicherbereich stammen und nicht aus Dateien importiert werden können...
(Das map.py in Py_CompileString ist ja imo nur für Tracebacks nötig und so müsste es eig. gehen...)

~Birne
BlackJack

Samstag 29. Mai 2010, 14:05

@Birne94: Die Klammern um die Bedingung sind nicht nötig und auf ``exec`` würde ich hier auch verzichten. Das ist komplexer als es sein müsste, denn Du kommst über `globals()` doch schon an das Funktionsobjekt heran! Das brauchst Du nur aufzurufen:

Code: Alles auswählen

def run_event(x, y):
    func = globals().get('event%dx%d' % (x, y))
    if func:
        func()
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Samstag 29. Mai 2010, 14:10

thx.
Trotzdem schlägt das Kompilieren des Scripts/Modul via Py_CompileString immer noch fehl, wobei es zB sich per IDLE etc. problemlos ausführen lässt. Hast du eine Idee, woran dies liegen könnte?

~Birne
BlackJack

Samstag 29. Mai 2010, 14:32

@Birne94: Fang doch mal ganz klein an, also ein Programm das nur diesen Quelltext als `std::string` enthält und den versucht auszuführen. Wenn das funktioniert kann man weiterschauen woran es vielleicht im echten Programm liegen kann. Sollte das *nicht* funktionieren hättest Du ja ein minimals Beispiel was Du uns komplett zeigen kannst, so das auch andere hier es mal ausprobieren können.
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Samstag 29. Mai 2010, 14:49

BlackJack

Samstag 29. Mai 2010, 15:10

@Birne94: Was machst Du jetzt in deinem richtigen Programm anders? Wo kommt da die Zeichenkette her? Bist Du sicher dass die nicht irgenwelche "komischen" Bytes enthält?
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Samstag 29. Mai 2010, 18:13

OK, hab das Problem gefunden. Es lag an der Newline-Kodierung von Windows (\r\n). C hat intern daraus dann irgendwas anderes gemacht (war in der Variablenüberwachung aber nicht dargestellt :o)

Trotzdem danke an alle ;)

~Birne
Antworten