2010-09-06 14 views
9

Ich habe mit der Einbettung verschiedener Skriptsprachen in eine C++ - Anwendung experimentiert, derzeit versuche ich Stackless Python 3.1. Ich habe mehrere Tutorials und Beispiele ausprobiert, die ich nur finden kann, um ein einfaches Skript aus einer Anwendung zu starten.Warum stürzt die Python/C-API bei PyRun_SimpleFile ab?

Py_Initialize(); 

FILE* PythonScriptFile = fopen("Python Scripts/Test.py", "r"); 
if(PythonScriptFile) 
{ 
    PyRun_SimpleFile(PythonScriptFile, "Python Scripts/Test.py"); 
    fclose(PythonScriptFile); 
} 

Py_Finalize(); 

Aus irgendeinem Grund, dieses Stück Code führt zu einer Zugriffsverletzung am Laufen:

PyRun_SimpleFile(PythonScriptFile, "Python Scripts/Test.py"); 

Ich habe für andere mit einem ähnlichen Problem gesucht online und fand nur eine. Ihre einzige Lösung war eine Problemumgehung, die nur in einer älteren Version von Python möglich scheint: Erstellen eines Python-Dateiobjekts und Zurückgeben des FILE* von diesem Python-Dateiobjekt an PyRun_SimpleFile. Solche Funktionsaufrufe sind jedoch nicht verfügbar, die Python 3.1-API erstellt Dateiobjekte aus einem Dateideskriptor und gibt Dateideskriptoren zurück, aber die PyRun_SimpleFile-Funktion benötigt weiterhin eine FILE*.

Ich bin ratlos, wie man irgendwelche Scripts von der Akte laufen lässt, kurz, die gesamte Akte in den Speicher manuell zu laden und es als eine riesige Schnur laufen zu lassen, sicher nicht eine praktische Lösung.

Was gibt? Wie kann ich diese Aufgabe ausführen, wenn die API einen internen Fehler aufweist?

Update: Ich habe es geschafft, Stackless Python 3.1 von der Quelle zu erstellen, und dennoch bleibt der Absturz trotz der Verwendung der gleichen C-Laufzeitbibliothek vollständig unverändert. Sowohl mein Projekt als auch die Stackless Python 3.1-Quelle werden mit dem C++ - Compiler und der C-Laufzeit von Visual Studio 2010 erstellt. Ich habe keine Ahnung mehr, was dieses Problem lösen könnte, außer Python zu modifizieren, um einen Dateinamen und nicht eine Datei * zu verwenden. Ein weiterer schrecklicher Workaround.

Antwort

3

Das klingt wie ein Problem von nicht übereinstimmenden APIs. Wenn Ihr Code und die Python-Laufzeit mit unterschiedlichen Compilern oder sogar verschiedenen Compiler-Optionen kompiliert wurden, kann der Zugriff auf FILE * zu einer Zugriffsverletzung führen. Können Sie überprüfen, ob Sie Ihren C-Code ordnungsgemäß erstellt haben?

Sie erwähnen, dass Sie Python in Ihre C++ - Anwendung einbetten. Denken Sie daran, dass Python C-Code ist, der als C-Code kompiliert wurde. Vielleicht ist das die Ursache des Problems?

+0

Aye, ich habe die Stackless Python 3.1-Bibliothek nicht selbst erstellt. Ich würde lesen, dass das Problem sehr wohl die Verwendung von FILE * s aus verschiedenen Laufzeiten sein könnte, weshalb die Problemumgehung darin bestand, der Python-Bibliothek zu ermöglichen, die FILE * zu erstellen und sie als Argument für die Funktion zurückzugeben. Also, habe ich keine andere Wahl als die Quelle zu erwerben und Stackless Python 3.1 selbst zu bauen? –

+0

Wenn Sie Ihren C-Code erstellen können, sollten Sie keine Schwierigkeiten mit dem Stackless-Code haben. –

5

Ihr Code funktioniert ordnungsgemäß auf meiner installierten Version von Python 2.6. Ich habe auch stackless 3.1.2 aus der Quelle gebaut und es hat richtig funktioniert. Das war mit g ++ 4.4.3 auf Ubuntu 10.04. Wenn Sie Windows verwenden, sollten Sie überprüfen, ob stackless und Ihr Code auf derselben C-Laufzeit basieren.

+0

Nun, das ist, wo ich in Schwierigkeiten gerate. Ich weiß, dass die C-Laufzeit anders ist. Ich verwende Visual Studio 2010 und bin mir ziemlich sicher, dass die meisten Python-Binärdateien mit Visual Studio 2008 erstellt werden. Ich habe versucht, die Stackless Python 3.1-Quelle zu erstellen, aber ich bin mir nicht ganz sicher, welche Bibliotheken, DLLs und Header wird gebraucht. Ganz zu schweigen von einigen Problemen mit einigen Erweiterungsmodulen, die aufgrund fehlender Dateien nicht erstellt werden. Die bereitgestellte Batch-Datei, um sie zu erstellen, hängt von mehreren anderen fehlenden Dateien ab, wie SVN installiert zu haben. –

+0

@Sion: Leider kann ich außer den Worten "check the docs" und "good luck" nichts mehr bieten. Ich habe keinen Zugriff auf einen Windows-Entwicklungscomputer, geschweige denn VS2010. Gibt es eine Möglichkeit, einen kleinen Wrapper für die relevanten Teile von stdio zu schreiben, der mit der richtigen Visual Studio-Version erstellt wurde? –

+0

Die Hilfe wird dennoch geschätzt, obwohl zu diesem Zeitpunkt sogar derselbe Compiler und dieselbe Laufzeit keine Auswirkung auf die Lösung des Problems hatten. Ich kann sehr gut versuchen, die Entwickler oder andere Python Gurus direkt zu kontaktieren. –

12

Ich war immer ein ähnlicher Absturz & die unten tat

PyObject* PyFileObject = PyFile_FromString("test.py", "r"); 
    PyRun_SimpleFileEx(PyFile_AsFile(PyFileObject), "test.py", 1); 

Beachten Sie, dass diese in Python 2.7 obwohl war. Ich weiß nicht, ob sich die API in 3.x geändert hat. Diese

+0

Wie Sie vermuteten, funktioniert dies nicht mit Python 3. – MasterMind

9

funktioniert für mich auf Python 3:

PyObject *obj = Py_BuildValue("s", "test.py"); 
FILE *file = _Py_fopen_obj(obj, "r+"); 
if(file != NULL) { 
    PyRun_SimpleFile(file, "test.py"); 
} 

Ich hoffe, es wäre nützlich sein.

+2

Funktioniert für mich, aber mit kleinen Änderungen: FILE * file = _Py_fopen ("test.py", "r +"); PyRun_SimpleFile (Datei, "test.py"); Dies sollte als Antwort markiert werden. – MasterMind

+1

@MasterMind: Das OP der Antwort wollte offensichtlich die '_Py_fopen_obj'-Funktion anstelle der' _Py_fopen'-Funktion aufrufen. Ich habe die Antwort entsprechend bearbeitet (also sollte der Code aus der Antwort jetzt out-of-the-box funktionieren). Ihre Lösung scheint jedoch einfacher/leichter zu sein. Aus irgendeinem Grund funktionierten beide Lösungen * nur *, wenn ich die 'const char *' Dateipfadvariable ** nach ** der 'Py_Initialize()' -Funktion deklariert hatte oder wenn ich die Zeichenkette wie in Ihrem Fall direkt einsetzte Beispiel. (Um ehrlich zu sein: Der Python C++ Wrapper ist ein Schmerz und könnte so viel einfacher sein) – mozzbozz

0

Wenn Sie Ihren Test mit VC 2010 erstellt haben, werden Sie definitiv Probleme haben - VC9 (VS 2008) und VC10 (VS 2010) haben inkompatible Support-DLLs, die normalerweise erforderlich sind (printf, Datei-I/O und diese Art implementieren der Sache).Sie können sie nicht mischen, wenn sie die Standardbibliotheken enthalten, die der Python-Build erstellt.

Sie haben immer die Möglichkeit, gcc (z. B. Cygwin oder mingw) zu verwenden oder Visual Studio 2008 Express herunterzuladen, was gut für Experimente in Python-Einbettung funktionieren sollte. Ich habe beide mit dem Standard Python 2.7.6 Build verwendet.

0

Und was ist mit dieser Lösung:

Py_SetProgramName(argv[0]); 
Py_Initialize(); 
PyRun_SimpleString("execfile(\"ex30.py\")"); 
Py_Finalize(); 

Wo ex30.py es der Name des Python-Skript, bei mir läuft.

Verwandte Themen