Ich möchte für meine Qt-Anwendung eine eigene Konsole haben und dahin die Standardausgabe umleiten (unter anderem, weil externe Bibliotheken die ja auch ab und an als Ausgabe von Fehlern/Infos benutzen, ansonsten würde ich einfach nicht cout benutzen)
Jetzt liest man dazu im Internet ja so einiges, zum Beispiel ist es sehr einfach, cout in eine Datei umzuleiten, indem man einfach den rdbuf umsetzt. Aber so wie ich das sehe, müsste ich ja einen eigenen rdbuf implementieren, nur weiß ich nicht genau wie (von std::streeambuf erben und bestimmte Methoden überschreiben? Nur welche genau?). Ich möchte dabei auch nicht einfach irgendeinen fiesen Hack machen, sondern es sollte nach Möglichkeit schon eine schöne Lösung sein.
Man stellt dann ja recht schnell fest, dass cout (und cerr und clog) auch nur die Standardausgabe benutzen, die man irgendwie per freopen umbiegen können soll. Damit würden dann vermutlcih auch Dinge aus print() in meiner Konsole landen. Wie ich das umimplementieren soll, weiß ich allerdings auch nicht.
Wie würde ich das am einfachsten und saubersten hinbekommen?
cout umleiten
cout umleiten
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: cout umleiten
Es ist schon mehrere Jahre her als ich sowas gemacht habe, daher weiß ich nicht mehr alles so genau. Die Methode mit C++‑Bordmitteln geht so:
Im Grunde musst du von std::streambuf ableiten und je nach Bedarf (Input oder Output) die virtuellen Funktionen (siehe http://www.cplusplus.com/reference/iostream/streambuf/) überschreiben. Dabei musst du halt entscheiden, ob du gepufferten oder ungepufferten IO möchtest. Beides geht auch, ist aber mit mehr Aufwand verbunden. Z.B. für die ungepufferte Ausgabe brauchst du nur overflow zu überschreiben. Input ist komplizierter — da gibt es Fallunterscheidungen (und da erinnere ich mich ohne Einlesezeit auch grad nicht mehr dran).
Für eine einfache Umleitung in eine Datei musst du allerdings keinen streambuffer selber schreiben, sondern verwendest den von std::fstream (zu bekommen per rdbuf())
Deutlich einfacher soll es aber mit Boost.IOStreams gehen. Damit habe ich damals aber nichts gemacht … Daher keine Hilfe von mir erwarten :-)
Im Grunde musst du von std::streambuf ableiten und je nach Bedarf (Input oder Output) die virtuellen Funktionen (siehe http://www.cplusplus.com/reference/iostream/streambuf/) überschreiben. Dabei musst du halt entscheiden, ob du gepufferten oder ungepufferten IO möchtest. Beides geht auch, ist aber mit mehr Aufwand verbunden. Z.B. für die ungepufferte Ausgabe brauchst du nur overflow zu überschreiben. Input ist komplizierter — da gibt es Fallunterscheidungen (und da erinnere ich mich ohne Einlesezeit auch grad nicht mehr dran).
Für eine einfache Umleitung in eine Datei musst du allerdings keinen streambuffer selber schreiben, sondern verwendest den von std::fstream (zu bekommen per rdbuf())
Deutlich einfacher soll es aber mit Boost.IOStreams gehen. Damit habe ich damals aber nichts gemacht … Daher keine Hilfe von mir erwarten :-)
Re: cout umleiten
Ja cool, mit boost::IOstreams ging das ganz gut, nach einiger Trickserei. Man musste nur eine sink-Klasse mit write Funktion schreiben, sich mit boost::iostreams::stream_buffer<ConsoleWidgetStream> einen Streambuf daraus basteln und dann diesen mit cout.rdbuf(bla) setzen.
Nächstes Problem: Ich benutze osgCompute, da werden Debugausgaben mithilfe von osg::notify gemacht. Ein kurzer Blick in den Quelltext (http://www.openscenegraph.org/projects/ ... tify?rev=2) lässt mich vermuten, dass dort ebenfalls einfach cout benutzt wird. Das Problem ist, das ganze ist eine dll, ich gehe einfach mal davon aus, dass osg::compute somit auch ein eigenes, globales, cout Objekt hat. Gibt es wohl irgendeine Chance, die Ausgaben davon auch umzuleiten? Weil nur für meine eigenen Ausgaben hätte sich die ganze Hackerei jetzt irgendwie nicht gelohnt, da hätte ich auch ohne Recherchieren eine eigene Log-Klasse schreiben können.
Nächstes Problem: Ich benutze osgCompute, da werden Debugausgaben mithilfe von osg::notify gemacht. Ein kurzer Blick in den Quelltext (http://www.openscenegraph.org/projects/ ... tify?rev=2) lässt mich vermuten, dass dort ebenfalls einfach cout benutzt wird. Das Problem ist, das ganze ist eine dll, ich gehe einfach mal davon aus, dass osg::compute somit auch ein eigenes, globales, cout Objekt hat. Gibt es wohl irgendeine Chance, die Ausgaben davon auch umzuleiten? Weil nur für meine eigenen Ausgaben hätte sich die ganze Hackerei jetzt irgendwie nicht gelohnt, da hätte ich auch ohne Recherchieren eine eigene Log-Klasse schreiben können.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: cout umleiten
Wie verwendest du denn die DLL? Linkst du sie dazu oder lädst du sie zur Laufzeit? In ersterem Fall könntest du mal versuchen stdout umzuleiten. Ich denke nämlich nicht, dass davon zwei Instanzen existieren, während ich mir bei cout nicht sicher bin. Das Umleiten geht z.B. mit dem guten alten freopen. Du solltest auch in Betracht ziehen, dass die DLL eventuell stderr (cerr) und nicht stdout (cout) verwendet.
Ohne Input kein Output.
Re: cout umleiten
Windows unterscheidet doch nicht zwischen stderr und stdout soweit ich weißBeRsErKeR hat geschrieben:Wie verwendest du denn die DLL? Linkst du sie dazu oder lädst du sie zur Laufzeit? In ersterem Fall könntest du mal versuchen stdout umzuleiten. Ich denke nämlich nicht, dass davon zwei Instanzen existieren, während ich mir bei cout nicht sicher bin. Das Umleiten geht z.B. mit dem guten alten freopen. Du solltest auch in Betracht ziehen, dass die DLL eventuell stderr (cerr) und nicht stdout (cout) verwendet.
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: cout umleiten
http://msdn.microsoft.com/en-us/library ... p/ms686244
STD_OUTPUT_HANDLE und STD_ERROR_HANDLE sind beide standardmäßig auf CONOUT$ gestellt; aber sie lassen sich seperat steuern.
STD_OUTPUT_HANDLE und STD_ERROR_HANDLE sind beide standardmäßig auf CONOUT$ gestellt; aber sie lassen sich seperat steuern.
Re: cout umleiten
antisteo hat geschrieben:Windows unterscheidet doch nicht zwischen stderr und stdout soweit ich weißBeRsErKeR hat geschrieben:Wie verwendest du denn die DLL? Linkst du sie dazu oder lädst du sie zur Laufzeit? In ersterem Fall könntest du mal versuchen stdout umzuleiten. Ich denke nämlich nicht, dass davon zwei Instanzen existieren, während ich mir bei cout nicht sicher bin. Das Umleiten geht z.B. mit dem guten alten freopen. Du solltest auch in Betracht ziehen, dass die DLL eventuell stderr (cerr) und nicht stdout (cout) verwendet.
Wenn du stdout umleitest und in der DLL auf stderr geschrieben wird, dann wird immer noch an die "alte Stelle" geschrieben. Dass anfangs beide auf die gleiche Stelle schreiben ist ja irrelevant. Es sind halt zwei verschiedene "Objekte".
Ohne Input kein Output.