C++ Subprocess zum aufruf eines Python Scripts mit "Stream" als Rückgabewert.



  • Hallo,
    ich würde gerne ein Python Script in meinem C++ Code aufrufen, und die Daten welche mir das Python Script zur Verfügung stellt, einlesen. Das Python Script läuft im Hintergrund weiter und sendet alle paar millisekunden neue Daten.

    Laufen soll das ganze unter Linux, vorerst Ubuntu dann auf einem Raspberry Pi.

    Beispiel/Simulator meines Python Scripts:

    #!/usr/bin/env python
    
    import time
    import sys
    
    value = 0
    while True:
        value = value + 1
        sys.stdout.write(str(value) + "\n")
        time.sleep(0.1)  
    
    

    Als subprocess Library habe ich folgendes gefunden:
    https://github.com/arun11299/cpp-subprocess

    Mein C++ Code:

    #include <iostream>
    #include "subprocess.hpp"
    
    using namespace std;
    using namespace subprocess;
    
    int main() {
    
    	auto p = Popen({"python3", "pyApp.py"}, output{PIPE});
    
    	while (true) {
    		//p.wait();
    		auto res = p.communicate();
    		cout << res.first.buf.data() << endl;
    	}
    
    	return 0;
    }
    
    

    Mein Problem ist, dass ich es einfach nicht hinbekomme, dass in der while Schleife die Daten empfangen werden.
    Ich würde gerne, wenn in Python neue Daten gesendet werden, dann die while Schleife in C++ abgearbeitet wird.

    Kann mir jemand Tipps geben wie dies funktioniert?

    PS:

    1. Ich kann auch das Python Script anpassen.
    2. Ich bin nicht abhängig von der subprocess Library, kann auch was anderes sein.

    godi



  • Ich bin jetzt kein PY experte ... aber: Sollte das Script nicht irgendeinen Rueckgabewert haben? Bzw irgendwann 'fertig' sein?

    Probier das mal ohne die WHILE TRUE im PY Script - kriegst du dann einen output?



  • Hallo,
    nein, das Python Script wird nicht 'fertig'.

    Das 'echte' Python script lest Daten von einer Hardware-Schnittstelle. Leider gibts hier keine C/C++ implementation dafür.
    Jetzt muss ich die Daten welche das Python script einließt irgendwie in meine C++ Applikaiton bekommen.



  • @godi sagte in C++ Subprocess zum aufruf eines Python Scripts mit "Stream" als Rückgabewert.:

    Beispiel/Simulator meines Python Scripts:

    Versuche mal, dein Script mit dem -u-Parameter aufzurufen. Also python3 -u pyApp.py - damit machst du stdout unbuffered. Ansonsten puffert Python die Ausgaben - aber das willst du ja genau nicht.



  • Der -u Parameter hat jetzt keine Änderung gebracht, ich behalte diesen aber vorerst, da dein Argument einleuchtend ist.



  • Ich glaube ich greife in meiner C++ Applikation nicht richtig auf die Pipe zu. Das programm bleibt bei p.communicate() hängen.
    Vielleicht bräuchte ich da eher etwas wie read new line...



  • @tbird sagte in C++ Subprocess zum aufruf eines Python Scripts mit "Stream" als Rückgabewert.:

    Ich bin jetzt kein PY experte ... aber: Sollte das Script nicht irgendeinen Rueckgabewert haben? Bzw irgendwann 'fertig' sein?

    Probier das mal ohne die WHILE TRUE im PY Script - kriegst du dann einen output?

    Hallo, ja wenn ich keinen "Stream" habe und mein Python programm beende, dann bekomme ich in meiner C++ Applikation daten.

    Wie bekomme ich es hin, dass ich die PIPE dauerhaft auslese?



  • Ich denke du muesstest deine While Schleife hier irgendwie anders aufbauen. Das Python Programm haengt in der Schleife fest und die C++ Pipe schafft es nicht, auf die Daten zuzugreifen.

    Evtl. was Event-Basiertes? Keine Ahnung, dazu kenne ich mich wie gesagt in PY zu wenig aus.



  • Du darfst communicate nicht verwenden, das wartet bis zum Ende des Python-Programms.

    #include <iostream>
    #include "subprocess.hpp"
    
    using namespace std;
    using namespace subprocess;
    
    int main() {
        auto p = Popen({"python3", "-u", "pyApp.py"}, output{PIPE});
        
        char buf[100] = {};
        while (fgets(buf, sizeof(buf), p.output())) {
            cout << "Read: " << buf << '\n';
        }
    }
    
    


  • Ich glaube, Du musst irgendwas finden, auf das beide Programme zugreifen können. Entweder einen gemeinsamen Speicherbereich (sehe ich hier mangels Wissen keine Möglichkeit) oder eine Datei (könnte ich mir vorstellen).



  • @Helmut-Jakoby sagte in C++ Subprocess zum aufruf eines Python Scripts mit "Stream" als Rückgabewert.:

    Ich glaube, Du musst irgendwas finden, auf das beide Programme zugreifen können. Entweder einen gemeinsamen Speicherbereich (sehe ich hier mangels Wissen keine Möglichkeit) oder eine Datei (könnte ich mir vorstellen).

    Pipes sind völlig in Ordnung.



  • @wob sagte in C++ Subprocess zum aufruf eines Python Scripts mit "Stream" als Rückgabewert.:

    Du darfst communicate nicht verwenden, das wartet bis zum Ende des Python-Programms.

    #include <iostream>
    #include "subprocess.hpp"
    
    using namespace std;
    using namespace subprocess;
    
    int main() {
        auto p = Popen({"python3", "-u", "pyApp.py"}, output{PIPE});
        
        char buf[100] = {};
        while (fgets(buf, sizeof(buf), p.output())) {
            cout << "Read: " << buf << '\n';
        }
    }
    
    

    Vielen Dank!
    So funktioniert es! 🙂



  • @godi sagte in [C++ Subprocess zum aufruf eines Python Scripts mit "Stream" als Rückgabewert.

    Das 'echte' Python script lest Daten von einer Hardware-Schnittstelle. Leider gibts hier keine C/C++ implementation dafür.

    Python nutzt doch auch nur irgend ein C Plugin dafür. Da sollte es möglich sein, die C Library direkt einzubinden.

    Jetzt muss ich die Daten welche das Python script einließt irgendwie in meine C++ Applikaiton bekommen.

    SHMEM wäre ein sinnvoller Versuch.



  • muss das python script denn wirklich ueber das c++ programm ausgefuehrt werden? Ich wurde das einfach standalone laufen lassen und die daten dann ueber ipc/rpc bereit stellen. A la named pipes, unix sockets, zeromq etc.


Anmelden zum Antworten