Python Plugins für C++



  • Ich beschäftige mich seit einiger Zeit sehr intensiv mit C++ und die Grundlagen laufen eigentlich ganz gut. Momentan beschäftige ich mich mit GUI-Programmierung mit Qt und ein wenig OpenGL für 3D-Grafik. Nebenbei nutze ich noch Fortran um einige bestimmte Teil zu schreiben, jedoch eher Übung oder Spielerei.

    Was mich interessieren würde - wie funktioniert ein Plugin-System? Ich würde gerne eine Möglichkeit einbauen die Software zu erweitern durch einfache Skripte. Es ist kein Problem Code in Python auszulagern aber ich weiß nicht so recht, wie man das nach dem Kompilieren schafft.

    Als einfaches Beispiel - ich habe ein kleines OpenGL-Fenster und dort einen Würfel, den man drehen kann. Person X möchte gerne ein Plugin schreiben womit man die Farbe ändern kann.

    Ich könnte mir vorstellen, dass man jeden Code, den man von C++ und Python aus verwenden will in eine Bibliothek schreibt. Dann greife ich von Python auf die Funktion zum Färben des Würfels zu und führe sie aus. Da beginnt aber mein Problem - wie kann ich es dem Programm zurückgeben? Woher weiß die Qt-Anwendung mit dem OpenGL-Fenster, dass die Funktion aus Python den Würfel färben will?



  • Es weiß niemand irgendwas. Du musst eine Schnittstelle definieren und die entsprechenden Funktionen implementieren. Irgendwo initialisierst du die Python Engine und übergibst C++ Objekte oder Funktionen (gibt verschiedene Möglichkeiten, ich weiß nicht, ob du dir schon angeschaut hast, wie das überhaupt funktioniert). Du definierst also die Schnittstelle und in Python wird es dann aufgerufen, z.B. irgendwie so:

    application.Settings.CubeColor = ...

    Das ist dann ein Wrapper um ein C++ Objekt, das auch kein OpenGl Fenster kennt und explizit berücksichtigt, wenn es den Würfel zeichnet.



  • wenn du ein Plugin System haben willst - sprich: dein C++ Programm ruft ein vom User erstelltes Python Skript auf:
    https://docs.python.org/2/extending/embedding.html

    wenn du 2 getrennte Prozesse haben willst, also einerseits deine Applikation, andererseits den Python Interpreter welcher das vom User erstellte Skript ausführt und mit deiner Applikation interagiert, so brauchst du eine Form von Interprozesskommunikation.
    Du kannst dir da selber was basteln, z.B. mit Sockets, oder du greifst auf bestehende Message Bus Systeme zu (z.B. zeroMQ), welche Nachrichten von einem Prozess an den anderen weiterreichen.



  • Okay erst einmal vielen Dank für die Hilfe. Ich muss da noch mehr lesen und rumprobieren, weil mir immer noch nicht so ganz klar ist woher mein Hauptprogramm weiß, dass die Datei mit dem Python-Script ausgeführt wurde und er Daten bekommt. Da hilft mir das mit der Interprozesskommunikation schon weiter.



  • SLx64 schrieb:

    Da hilft mir das mit der Interprozesskommunikation schon weiter.

    Ich würde auf jeden Fall den "embedding" Weg gehen. Python als Library einbinden und in deinem Prozess selber ausführen.
    Dein Hauptprogramm weiß, dass ein Pythonscript ausgeführt wurde, weil es das selber ausführt 😉 Du musst bestimmte Stellen definieren, an denen du die Scripte aufrufst. z.B., wenn ein Modell geladen wird. Dann führst du explizit die Scripte aus, übergibst denen die Objekte, und wenn sie die Objekte verändern, dann hast du auch die geänderten Daten.



  • Mechanics schrieb:

    Ich würde auf jeden Fall den "embedding" Weg gehen. Python als Library einbinden und in deinem Prozess selber ausführen.
    Dein Hauptprogramm weiß, dass ein Pythonscript ausgeführt wurde, weil es das selber ausführt 😉 Du musst bestimmte Stellen definieren, an denen du die Scripte aufrufst. z.B., wenn ein Modell geladen wird. Dann führst du explizit die Scripte aus, übergibst denen die Objekte, und wenn sie die Objekte verändern, dann hast du auch die geänderten Daten.

    Genau das ist mein Problem. Wenn ich die Skripte schon vorher kenne, kann ich sie problemlos einbinden oder das ganze gleich in C++ schreiben. Mir geht es aber eher darum anderen Nutzern eine Möglichkeit zu bieten, dass kompilierte Programm zu erweitern. 🙂

    Es muss auch nicht unbedingt Python sein aber das kann man schnell lernen und bekommt gewisse Sachen schneller hin.



  • Ich versteh nicht, was du nicht verstehst 😉 Du hast ein Unterverzeichnis "plugins", wo die Scripte liegen können. Du kennst sie nicht und weißt nicht, was drin ist. Aber an einer bestimmten Stelle in deinem Programm, z.B. eben beim Laden von einem Modell, sagst du dann, so jetzt will ich die Plugins ausführen. Gehst also alle Dateien in dem plugins Verzeichnis durch, lädst sie in die Python Engine, übergibst denen paar Objekte von dir als Parameter und führst die aus.



  • Ah okay ich glaub jetzt hab ich es verstanden. Ich habe einen Haufen Funktionen, die ich zur Verfügung stelle und führe dann einfach ein Skript aus dem Ordner aus und in diesem ist beschrieben welche Funktion ausgeführt wird. Es kommt dann irgendwas zurück. Es wäre also genau das gleiche als wenn ich das vorher einbinde?



  • SLx64 schrieb:

    Es wäre also genau das gleiche als wenn ich das vorher einbinde?

    Und was heißt das jetzt?



  • Mechanics schrieb:

    SLx64 schrieb:

    Es wäre also genau das gleiche als wenn ich das vorher einbinde?

    Und was heißt das jetzt?

    Dass ich direkt Teile in Python schreibe und diese beim kompilieren schon eingebunden sind und er sie zur Laufzeit dann ausführt.



  • Ich seh jetzt keinen Unterschied bzw. versteh immer noch nicht so ganz, was du damit sagen willst. Dem C++ Compiler ist dein Python Code egal. Python wird normalerweise eh zur Laufzeit interpretiert. Ist also völlig egal, wann du den Code schreibst.



  • Mechanics schrieb:

    Ist also völlig egal, wann du den Code schreibst.

    Genau das mein ich. ^^


Anmelden zum Antworten