cout umleiten

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Jonathan
Establishment
Beiträge: 2660
Registriert: 04.08.2004, 20:06
Kontaktdaten:

cout umleiten

Beitrag von Jonathan »

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?
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Biolunar
Establishment
Beiträge: 154
Registriert: 27.06.2005, 17:42
Alter Benutzername: dLoB

Re: cout umleiten

Beitrag von Biolunar »

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 :-)
Benutzeravatar
Jonathan
Establishment
Beiträge: 2660
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: cout umleiten

Beitrag von Jonathan »

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.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: cout umleiten

Beitrag von BeRsErKeR »

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.
antisteo
Establishment
Beiträge: 941
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: cout umleiten

Beitrag von antisteo »

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.
Windows unterscheidet doch nicht zwischen stderr und stdout soweit ich weiß
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8350
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: cout umleiten

Beitrag von Krishty »

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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: cout umleiten

Beitrag von BeRsErKeR »

antisteo hat geschrieben:
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.
Windows unterscheidet doch nicht zwischen stderr und stdout soweit ich weiß

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.
Antworten