Python einbinden in C Programm
-
Hi!
Ich habe ein großes Problem. Ich versuche eine Anbindung an Python zu erstellen.
1. Das Python Framework ist in mein Projekt eingebunden
2. DIe Headerdatei Python.h habe ich auch erfolgreich eingebunden.Mein großes Problem, das Python Skript muss in einem seperaten Skript ausgeführt werden, jedoch erhalte ich von Python einen "BUS error" wenn ich die kompilierte Datei starte.
Eventuell mag sich jemand mal den Code anschauen? Ich wäre demjenigen sehr dankbar.
Bye!#include <stdio.h> #include <Python/Python.h> int main(int argc, char * argv[]) { Py_Initialize(); PyEval_InitThreads(); PyThreadState* mainThreadState = NULL; mainThreadState = PyThreadState_Get(); PyEval_ReleaseLock(); PyEval_AcquireLock(); PyInterpreterState * mainInterpreterState = mainThreadState->interp; PyThreadState* myThreadState = PyThreadState_New(mainInterpreterState); PyEval_ReleaseLock(); PyEval_AcquireLock(); PyThreadState_Swap(myThreadState); PyRun_SimpleString("import sys\n"); PyRun_SimpleString("sys.stdout.write('hallo')\n"); PyThreadState_Swap(NULL); PyEval_ReleaseLock(); PyEval_AcquireLock(); PyThreadState_Swap(NULL); PyThreadState_Clear(myThreadState); PyThreadState_Delete(myThreadState); PyEval_ReleaseLock(); PyEval_AcquireLock(); Py_Finalize(); return 0; }
-
Hi!
Ich meinte nicht "in einem seperaten Skript" sondern in einem seperaten "Thread"
-
Hat keiner eine Idee?
-
Hallo
Vermutlich hat dein Problem nichts mit C++ zu tun sondern mit Python bzw. der Python-Library. Du solltest also die Dokus zu Library sowie passende Foren aufsuchen.
bis bald
akari
-
Wie wär's denn mal mit nem Backtrace?
-
Hm, du hast ein Problem mit Python und C, und postest deswegen in einem C++-Forum?

Aber zum Thema: Wie wäre es denn, wenn du in C einen neuen Thread erzeugst, und dann alles was mit Python zu tun hat, also auch das Py_Initialize() etc, in diesem Thread ausführst? Dann könntest du dir den ganzen Krampf mit Python's Global Interpreter Lock sparen...
-
Hi!
Hoppala, ich habe das Problem ins CPP Forum geschrieben weil ich es in C++ benötige, aber eigentlich hast du Recht

Frage, du erzeugst also einen Thread in C? Hmm.. Damit brauch ich mich also um Threads in Python nicht mehr kümmern?
Danke

-
Wenn du eh C++ benutzt, warum dann nicht Boost.Python?
Das macht natürlich am Threading (leider) nichts, aber der Rest des Codes sollte dadurch hübscher werden.Bei mir sieht das dann so aus:
#include <boost/python.hpp> // ... namespace bp = boost::python; void python_thread (bp::str path, bp::object global) { try { bp::exec_file (path, global, global); } catch (boost::python::error_already_set const&) { PyErr_Print (); } catch (std::exception const& exc) { std::cerr << exc.what () << std::endl; } catch (...) { std::cerr << "Unknown exception in Python thread." << std::endl; } game_window::instance ().close (); } int main (int argc, char** argv) { try { PyEval_InitThreads (); Py_Initialize (); PySys_SetArgv (argc, argv); bp::object global = bp::import ("__main__").attr ("__dict__"); bp::object builtin = bp::import ("__builtin__").attr ("__dict__"); bp::object star (bp::handle<> (PyModule_New ("_star"))); builtin["_star"] = star; { bp::scope s (star); module_star (); } bf::path main_py ("python/main.py"); boost::thread py_thread ( boost::bind (&python_thread, bp::str (main_py.native_file_string ()), global) ); game_window::instance ().draw (); py_thread.join (); } catch (boost::python::error_already_set const&) { PyErr_Print (); } }In module_star werden dann mit def und class_ von Boost.Python die Klassen und Funktionen definiert, die dann im Pythonskript (hier "python/main.py") im Modul _star zu sehen sind.
-
Hi!
Super, danke schön für die Einführung. Ich bin jetzt aber wirklich mal blöd.
Boost ist eine Bibliothek die mir den Zugang zu Python vereinfacht, korrekt? Und Boost ist nicht standardmäßig in Python mit drin sondern muss seperat heruntergeladen werden!?
Ich brauche also Boost 1.3.5 und Jam, sehe ich das richtig?
Danke schön

-
DonnerCobra schrieb:
Frage, du erzeugst also einen Thread in C? Hmm.. Damit brauch ich mich also um Threads in Python nicht mehr kümmern?
Genau. Python interessiert es nicht, wieviele Threads dein Programm hat, solange sämtliche Python-Funktionen in ein und demselben Thread aufgerufen werden.
Solltest du allerdings dadurch dann aufwendig deine Threads C++-seitig miteinander synchronisieren müssen, ist damit natürlich auch nichts gewonnen. Kommt also ein bißchen darauf an, was du machen willst.Boost ist eine Bibliothek die mir den Zugang zu Python vereinfacht, korrekt? Und Boost ist nicht standardmäßig in Python mit drin sondern muss seperat heruntergeladen werden!?
Ich brauche also Boost 1.3.5 und Jam, sehe ich das richtig?
Soweit richtig. Boost.Python ist allerdings auch extrem komplex und braucht, sobald man nicht ganz triviale Dinge damit machen will, eine nicht zu unterschätzende Einarbeitungszeit (deutlich mehr als das Python-C-API). Ich denke also das lohnt sich nur, wenn deine C++/Python-Schnittstelle einen gewissen Umfang haben wird, zumal Boost.Python auch den Compiler ganz schön ins Schwitzen bringt...
-
Ich würde mich dem Thread gerne anschließen, zumal ich auch boost.python verwende.
Meine Frage ist nun wenn ich alles brav kompiliert habe und nun ein EXE file zu Verfügung habe, was brauche ich alles damit ich die Python Scripts ausführen kann?
Gehen wir von meiner Situation aus, das auf dem anderen Host/Rechner nichts installiert werden darf/kann.
Dachte da an ein Zipfile oder so wo die benötigten sachen für Python drinnen sind und beim Programmstart entpacke ich einfach dieses Zip Archiv. Nur was benötigt Python alles?Lg _freeze_
-
Im Prinzip nichts. Der Interpreter wird mit einkompiliert, du musst nur die verwendeten Module beifügen.
-
DonnerCobra schrieb:
Boost ist eine Bibliothek die mir den Zugang zu Python vereinfacht, korrekt? Und Boost ist nicht standardmäßig in Python mit drin sondern muss seperat heruntergeladen werden!?
Boost und Python haben im ersten Moment nichts miteinander gemeinsam. Boost ist eine Bibliothekssammlung die unter anderem (neben sehr vielen mehr) auch eine Bibliothek für Python hat. Imho sollte jeder der sich ernster mit C++ auseinander setzt auch Boost kennen.
cu André
-
Genau die Module meinte ich. Da bei meiner Applikation jeder Benutzer selbst skripte erstellen kann wollte ich wissen was ich alles brauche. Gehen wir von dem schlimmsten aus, das irgendwann alles gebraucht wird. Genügt es das "C:\Python25\Lib" Verzeichnis zu packen und mitzugeben? oder benötigt man sonst noch was ausser das Lib Verzeichnis?
Lg _freeze_
P.S.: Da hier anscheinend mehrere Leute sind die sich mit Python bzw. Boost.Python gut auskennen. Wie bekomme ich den Backtrace in eine Variable? Für Konsolen Anwendungen passt das ausgeben ja eh. Was aber wenn man eine GUI entwickelt, da wäre der Backtrace in einer MessageBox oder was auch immer nicht schlecht.
-
freeze schrieb:
Genau die Module meinte ich. Da bei meiner Applikation jeder Benutzer selbst skripte erstellen kann wollte ich wissen was ich alles brauche. Gehen wir von dem schlimmsten aus, das irgendwann alles gebraucht wird. Genügt es das "C:\Python25\Lib" Verzeichnis zu packen und mitzugeben? oder benötigt man sonst noch was ausser das Lib Verzeichnis?
Ich bezweifle, dass du alles daraus brauchst. Da sind ja bestimmt auch Sachen drinne, die dein Programm torpedieren könnten, die musst du nun nicht mitliefern. Außerdem vereinfacht sich die Sache für dich, wenn du nur echte Python-Bibliotheken (keine DLLs) mitnimmst. Wie das ganze lizenztechnisch ist weiß ich aber auch nicht.
Treff halt ne sinnvolle Vorauswahl, der Benutzer kann sich den Rest selbst zusammensuchen. Du musst den Pfad übrigens in deinem Programm dann zu sys.path hinzufügen (kannst ja mal schauen, ob das mit der C-API geht, ansonsten einfach per exec oder mit import("sys").attr("path") += str("pfad")).Da hier anscheinend mehrere Leute sind die sich mit Python bzw. Boost.Python gut auskennen. Wie bekomme ich den Backtrace in eine Variable? Für Konsolen Anwendungen passt das ausgeben ja eh. Was aber wenn man eine GUI entwickelt, da wäre der Backtrace in einer MessageBox oder was auch immer nicht schlecht.
-
.filmor schrieb:
Ich meinte C/C++ technisch, ausgehend von der Python C Api beispielsweise:
try { . . . }catch(PythonFehler &e) { PyErr_Print(); MessageBox("HIER KOMMT DER PYTHON FEHLER (BACKTRACE) REIN"); }Lg _freeze_
-
catch (bp::error_already_set const&) { bp::str blubb = bp::import("sys").attr("stderr").attr("data"); // mit blubb rumspielen, zB zu std::string konvertieren oder sowas }
-
@.filmor: Danke werde die Fehlerbehandlung mal so probieren.
Jedoch zu meinem vorherigen Posting war noch keine klare Aussage getroffen worden. genügt es das ganze bzw. Teile vom Lib Verzeichnis mitzugeben oder brauche ich sonst noch etwas? Habe auch irgendwo mal gelesen das es genügt ein Zip file zu generieren da Python in das Zip file schaut. Hast Du damit vielleicht schon erfahrung gesammelt?
Lg _freeze_
-
Das Thread-Hijacking hier läuft langsam ein bisschen aus dem Ruder

Die nächste Frage bitte in nem eigenen Thread.Wie ich schon sagte, der Interpreter wird mit einkompiliert (wenn es dynamisch gelinkt wird muss selbstverständlich die python.dll und boost_python.dll bzw. so beiliegen).
Ansonsten wird nichts weiter benötigt. Die Teile der Bibliothek, die du für sinnvoll erachtest (!= die gesamte Laufzeitbibliothek!) kannst du in ein zusätzliches Unterverzeichnis lib tun, dass dann beim Programmstart Python bekannt gemacht wird (also zu sys.path hinzugefügt wird).Ich weiß nicht, ob Python von Hause aus in .zip-Dateien nach Modulen schauen kann, aber ich denke, dass man diese Verhalten nachrüsten könnte (Stichwort __import__).
-
Vielen Dank für Deine Antwort,
werde bei meiner nächsten Frage einen neuen Thread eröffnen.

Nichts für ungutLg _freeze_