How does JUCE redirect stdout?


#1

We are building a graphics application using VisualStudio. What does JUCE do with stdout (how does it remap that output stream)?

Running my JUCE application in a bash shell from the command line, I see strings sent to stdout.
Doing the same thing in a CMD shell (e.g., gitCMD, PowerShell) I see nothing.

A generic application built with VisualStudio exhibits the behavior I would expect, i.e., I see strings sent to stdout in any shell I use. So I am inferring that JUCE manages / redirects streams in specific way that interacts with Windows streams.

I have looked on the forum and elsewhere and found similar questions, but no answers to this specific issue.

Thank you,
Erik


DBG vs printf & std::cout
#2

This is nothing specific to JUCE. Standard streams are not connected to anything by default on Windows GUI applications. I guess the bash shell is doing something special to connect these streams anyway.

If you always want to see stuff printed to stdout you have to build your application as a “console application”. The downside is that your application then always shows both your GUI and a console window.


#3

If you need to post some kind of messages to a console in a JUCE program, the best way to do it is with the global instance of the logger class. This will post the messages to the VS/Xcode output panes and the terminal on Linux.

Like @roeland said you can set the vcxproj to be a command line app, but you have to reconfigure it a few times.


#4

Thank you Jon and Roeland. I appreciate your taking the time to reply, and giving clear, concise, helpful answers.

I guess that building as a console app (which I have done successfully) is the only way to do this, but we really don’t want our app to pop up a console window when the user starts the program.

We are using the logger class (but thanks for mentioning it, in case we weren’t).

Best regards,
Erik


#5

If you’re really keen, there are ways around this, you can look around on StackOverflow, eg. “Can one executable be both a console and GUI application?” Although that question is about C#, the principle is independent of the language you’re using.


#6

Here is what I’m using in order to have cout and cerr output to the cmd shell if there is one:

  bool ok = AttachConsole(ATTACH_PARENT_PROCESS);
   /* AttachConsole will fail for console apps (with a main() {} ),
      and for gui apps not launch from a win32 console or a cygwin console */
   if (ok) {
     bool redir_cout = false, redir_cerr = false;
     if (_fileno(stdout) == -1 || _get_osfhandle(_fileno(stdout)) == -1) {
       redir_cout = true;
       freopen("CONOUT$", "w", stdout);
     }
     if (_fileno(stderr) == -1 || _get_osfhandle(_fileno(stderr)) == -1) {
       redir_cerr = true;
       freopen("CONOUT$", "w", stderr); // won't work with CONERR 
     }
     if (redir_cout || redir_cerr) {
       std::ios::sync_with_stdio();
     }
  }

It work decently, at least for debugging purposes.


#7

i’ve also seen this in the AppVeyor powershell console, where no output is shown.

would be cool to integrate this in the library.


#8

I wouldn’t say so, because the program still doesn’t behave as a console app. The output goes to the console, but other than that, you still go back to the prompt immediately after launching the app, and anything you type will be interpreted as new commands by CMD.

Contrast this with the usual behaviour of console applications: you only go back to the prompt after the program exits, and input goes to the standard input stream of the program.


#9

I just pushed some code to develop to make a JUCE GUI app work with std::cout/cerr/cin on the WIndows console if (and only if) it was launched from that console. Works nicely in cmd.exe and PowerShell on my machine (tested it with the Projucer where the command-line features were actually broken on WIndows because of this)


#10

great thanks! will try asap


#11

With this fix, Projucer will indeed print output to the console. But you cannot get input via stdin. CMD in interactive mode will start GUI applications in the background, so CMD will already display a prompt and accept new commands while your application is still running.

This is the result on my box: note how CMD prints the prompt (C:\JUCE>) before Projucer prints any output.

C:\JUCE>Projucer.exe --obfuscated-string-code "Hello world!"

C:\JUCE>String createString()
{
    String s2;  s2 << 'r' << 'l' << 'd' << '!';
    String s0;  s0 << '"' << 'H' << 'e' << 'l';
    String s1;  s1 << 'l' << 'o' << ' ' << 'w' << 'o';
    String s3;  s3 << '"';

    String result = (s0 + (s1 + (s2 + s3)));

    jassert (result == "Hello world!");
    return result;
}

You also cannot redirect the output to a file. Projucer.exe --help > help.txt will still print everything to the console, and you’ll get an empty text file.


#12

Well, OK, to be honest I can’t figure out how to do this correctly (getting cout to work was hard enough…) but if someone else has a fix for that I’d be happy to merge it in!


#13

As outlined in the StackOverflow article (and the blog posts linked from there) what you’re trying to do is not possible. This is a limitation of the Windows platform. Windows treats GUI applications and console applications in a different way.

Raymond Chen explains why it’s impossible, Junfeng Zhang explains how some other applications work around this limitation.

For the Projucer it doesn’t matter much since that app only produces output, so at least with the above fix it will print something on the console.


#14

A couple of links before I lose them:

http://sdl.beuc.net/sdl.wiki/FAQ_Console

and …

π