Hur kan jag streama printf i C++ för ImGui?

Permalänk

Hur kan jag streama printf i C++ för ImGui?

Jag har mycket C kod som använder printf. Det är C-kod för konsollapplikationer. C-koden används tillsammans med C++ i större applikationer som är grafiska. Den grafiska applikationen använder ImGui. ImGui är ett bibliotek för att hantera knappar, menyer, grafer med mera. ImGui är rikigt snabbt då den körs i realtid, till skillnad från Qt eller Visual Studio som är händelsestyrda.

Hur som helst. Jag måste streama min printf så jag kan få in det i ImGui. Är det någon som vet hur man gör?
Just nu har jag två fönster öppna. En konsol och en grafisk. Jag vill implementera konsolen i den grafiska applikationen som en rullande listbox.

Permalänk
Hedersmedlem

Du borde kunna styra om stdout till en pipe som du kan läsa i den grafiska applikationen. Gäller det Windows eller linux?

*Sedan är det ju händelsestyrning nödvändigt i andra ramverk, men normalt är det ju önskvärt då det bättre beskriver uppgiften man försöker lösa. Det behöver inte heller påverka prestandan.
Och Visual studio är ju en utvecklingsmiljö som kan användas för många olika ramverk (inklusive ovan nämnda).

Permalänk
Skrivet av Elgot:

Du borde kunna styra om stdout till en pipe som du kan läsa i den grafiska applikationen. Gäller det Windows eller linux?

*Sedan är det ju händelsestyrning nödvändigt i andra ramverk, men normalt är det ju önskvärt då det bättre beskriver uppgiften man försöker lösa. Det behöver inte heller påverka prestandan.
Och Visual studio är ju en utvecklingsmiljö som kan användas för många olika ramverk (inklusive ovan nämnda).

Detta gäller för Windows.

Så det jag försöker göra just nu...är inte något att rekommendera?

Permalänk
Hedersmedlem
Skrivet av heretic16:

Detta gäller för Windows.

Så det jag försöker göra just nu...är inte något att rekommendera?

Jodå, det låter som ett roligt projekt (jag håller bara inte med om att imgui alltid är ett överlägset alternativ).

Permalänk

Ett alternativ vore att skriva en egen printf som istället för att anropa WriteFile (eller vad nu standardbibiliteksvarianten gör) skickar det vidare till imgui.

Permalänk
Skrivet av Elgot:

Jodå, det låter som ett roligt projekt (jag håller bara inte med om att imgui alltid är ett överlägset alternativ).

Okej. Ja, men då ska jag försöka få till så printf kan skickas till någon textruta.

Det finns inget bättre än ImGui. Tro mig, jag har testat både QT, wxWidgets och Microsofts Visual C++.
Visst, QT var bra....men allt var en klass. Att inkludera C filer i QT var in princip nästan omöjligt. QT hade något fint också som heter Signals & Slots. Detta var bra, men det var enormt grötigt när man skulle skicka massa signaler fram och tillbaka. Det blev som spagettikod.

Dessutom så är typ wxWidgets och Microsoft Visual C++ rena rama stenåldern. Gör folk ens grafiska applikationer i dessa ramverk nu för tiden?

Den uppfattning som jag har så är det mest bara mobila och webapplikationer som gäller. Grafiska skrivbordsapplikationer är den gamla skolan.

Permalänk
Skrivet av Ingetledigtnamn:

Ett alternativ vore att skriva en egen printf som istället för att anropa WriteFile (eller vad nu standardbibiliteksvarianten gör) skickar det vidare till imgui.

Kan man överskrida printf i C++? Typ som man gör i Java.

Permalänk
Hedersmedlem
Skrivet av heretic16:

Okej. Ja, men då ska jag försöka få till så printf kan skickas till någon textruta.

Jag tror att mitt ovanstående förslag är det mest transparenta. Man kan definiera om printf, men man måste verkligen göra det på alla ställen om man inte vill missa något.

Skrivet av heretic16:

Det finns inget bättre än ImGui. Tro mig, jag har testat både QT, wxWidgets och Microsofts Visual C++.
Visst, QT var bra....men allt var en klass. Att inkludera C filer i QT var in princip nästan omöjligt. QT hade något fint också som heter Signals & Slots. Detta var bra, men det var enormt grötigt när man skulle skicka massa signaler fram och tillbaka. Det blev som spagettikod.

Jag tror att du har en ofullständig bild av hur Qt (och kanske andra) ramverk är tänkta att användas. Visst kan man skriva spagettikod om man vill, men det är inte en nödvändig följd av ramverket. Visst blir det många klasser, men är väl inte nödvändigtvis en nackdel? Det är kanske ovant om man kommer från c, men om man kommer från Java är det väl inget nytt?
Och c-kod kan man använda direkt (antingen kompilera som c++ eller länka in; Qt gör inget svårare än c++ i sig).

Skrivet av heretic16:

Dessutom så är typ wxWidgets och Microsoft Visual C++ rena rama stenåldern. Gör folk ens grafiska applikationer i dessa ramverk nu för tiden?

Det håller jag däremot med om (om du med visual c++ menar win32, mfc och liknade).

Permalänk
Hedersmedlem

@heretic16 StdOutRedirect-klassen här ser lovande ut:
https://stackoverflow.com/a/617158

Permalänk
Medlem

Att ändra koden i en befintlig konsollapplikation känns arkitektoniskt tveksamt och antagligen onödigt, även om man har full kontroll på koden.

I POSIX så hade man kört pipe/fork/close/dup2/exec för att starta konsollapplikationen från GUI-applikationen (konsolappen blir en child-process) och kunna läsa konsollappens stdout (och/eller stderr) från en pipe (dvs fildeskriptor). Möjlighet att skriva till konsollapplikationens stdin finns också men tycks vara helt onödigt i det här fallet. Typ såhär, inget perfekt exempel, men borde visa principen. Om exakt samma teknik går att använda i Windows vet jag inte.

Sedan är det mest en fråga om att läsa från pipen på rätt sätt och skicka text till GUI:et, på dess specifika sätt.

Rimligen borde det även funka att skriva en minimal .bat-fil som startar bägge programmen och pipe:ar konsollapplikationens stdout till GUI:ets stdin, men den lösningen blir mindre generell, då kan man bara integrera ett enda konsollprogram, lösningen ovan går att generalisera till flera.

Permalänk
Skrivet av heretic16:

Kan man överskrida printf i C++? Typ som man gör i Java.

Det är bara ett funktionsanrop. Om du gör din egen version och länkar med kommer länkaren ta den före versionen som finns i standardbiblioteket. Dock skall du då göra din egen deklaration av printf instället för den i stdio.h. Versionen i standardbiblioteket har ofta en en hel del attribut som gör att kompilatorn "vet" att det är printf-funktionen i standardbiblioteket som anropas och den kan göra speciella optimeringar för att den vet hur den funktionen beter sig. Om du byter ut printf och kör med din egen version så skall du ha en deklaration utan dessa attribut.

Permalänk
Skrivet av Ingetledigtnamn:

Det är bara ett funktionsanrop. Om du gör din egen version och länkar med kommer länkaren ta den före versionen som finns i standardbiblioteket. Dock skall du då göra din egen deklaration av printf instället för den i stdio.h. Versionen i standardbiblioteket har ofta en en hel del attribut som gör att kompilatorn "vet" att det är printf-funktionen i standardbiblioteket som anropas och den kan göra speciella optimeringar för att den vet hur den funktionen beter sig. Om du byter ut printf och kör med din egen version så skall du ha en deklaration utan dessa attribut.

Alltså om jag definierar en printf-funktion så kommer min kompilator att använda denna istället?
Jag undrar hur printf fungerar i C, den verkar ha oändligt med argument, trots att C måste ha fixerade argument.

Permalänk
Skrivet av Elgot:

Jag tror att mitt ovanstående förslag är det mest transparenta. Man kan definiera om printf, men man måste verkligen göra det på alla ställen om man inte vill missa något.

Jag tror att du har en ofullständig bild av hur Qt (och kanske andra) ramverk är tänkta att användas. Visst kan man skriva spagettikod om man vill, men det är inte en nödvändig följd av ramverket. Visst blir det många klasser, men är väl inte nödvändigtvis en nackdel? Det är kanske ovant om man kommer från c, men om man kommer från Java är det väl inget nytt?
Och c-kod kan man använda direkt (antingen kompilera som c++ eller länka in; Qt gör inget svårare än c++ i sig).

Det håller jag däremot med om (om du med visual c++ menar win32, mfc och liknade).

Det går inte överskrida printf som i Java?

QT är bra. Men problemet med QT är att det är gammskola. Dessutom att skriva C++ kod för GUI så får man vara beredd på massiva filer och massvis med filer. Med ImGui så blir det inte så. Här har dom tänkt till.

Ja. QT, Visual C++, Win32, MFC osv. Den gamla skolan.
C++ är dock skithäftigt.

Permalänk
Medlem
Skrivet av heretic16:

Alltså om jag definierar en printf-funktion så kommer min kompilator att använda denna istället?
Jag undrar hur printf fungerar i C, den verkar ha oändligt med argument, trots att C måste ha fixerade argument.

Du kan ha variabelt antal argument till en funktion i C. Det är helt standard och har fungerat sedan tidernas begynnelse, eller näst intill.
printf(), scanf() m.fl. använder standard mekanismen för variabla antal argument.

Du kan använda din egen printf() i C program, men du måste vara väldigt petig med vilka headers du inkluderar och hur du länkar för att det skall fungera korrekt. Rekommenderas inte om du kan undvika det.

Permalänk
Skrivet av heretic16:

Alltså om jag definierar en printf-funktion så kommer min kompilator att använda denna istället?
Jag undrar hur printf fungerar i C, den verkar ha oändligt med argument, trots att C måste ha fixerade argument.

Om du har en objektfil på kommandoraden till länkaren kommer funktioner i den ha högre prioritet än de som finns i ett bibliotek.

https://en.cppreference.com/w/c/variadic

Men som Erik skrev, du får vara försiktig så att du inte mixar standardbibliotekets printf med din egen. Du får isolera de bitar som använder stdio och de som använder din egna printf.

Permalänk
Hedersmedlem
Skrivet av heretic16:

Alltså om jag definierar en printf-funktion så kommer min kompilator att använda denna istället?
Jag undrar hur printf fungerar i C, den verkar ha oändligt med argument, trots att C måste ha fixerade argument.

Det finns metoder för att ha godtyckligt antal argument. Just detta var en grej som länge var fanns i c men inte c++, men på senare år har det kommit även dit.

Skrivet av heretic16:

Det går inte överskrida printf som i Java?

Jo, om du definierar en egen funktion som heter likadant och ser till att den är definierad på alla ställen där printf anropas kommer den att användas istället. Fast då gäller det att du modifierar koden på många ställen och kompilerar om. Ett annat alternativ är som sagt att bygga en egen printf som delat bibliotek och se till att det är högre prioriterat än standardbibliotekets när programmet kör (jag vet dock inte hur lätt detta är i Windows).

Skrivet av heretic16:

QT är bra. Men problemet med QT är att det är gammskola.

Det kan man kanske hävda, fast det är ju inte nödvändigtvis en nackdel. Det moderna är ju inte heller imgui utan snarare nodejs och electron…

Skrivet av heretic16:

Dessutom att skriva C++ kod för GUI så får man vara beredd på massiva filer och massvis med filer. Med ImGui så blir det inte så. Här har dom tänkt till.

Nja, det som blir mycket kod är väl oftast själva funktionen? För att rita en knapp (eller tio) behöver man ju typiskt inte skriva en enda rad, och med imgui måste man ju istället bry sig om renderingsloopar och liknade. Det är ju inget större problem om man redan har en sådan (och det är väl främst det fallet man riktar sig mot) men annars är det kanske fler detaljer än de flesta vill bry sig om?