WE DON'T NEED ANY WORKAROUNDS! A WORKAROUND IS IN FACT A CRUTCH AND DOWNRIGHT SURRENDER! I BELIEVE WE CAN KILL THE BEAST IN ITS DEN!There's absolutely no magic in the creation of FBSL console. Everything goes through AllocConsole(), same as in your Console.inc file.
From the system perspective, FBSL is always a monolithic GUI process. Its dynamically compiled DynC and DynAsm blocks are simply its subroutines that serve the needs of an FBSL script alonside the GCC subroutines of FBSL's virtual machine that execute the mixture of tokenized/bytecoded BASIC code proper. (Not all FBSL's BASIC constructs can be easily bytecoded so FBSL sometimes falls back to incremental interpretation, e.g. in the evaluation frames of For/Next loops.)
DynC and DynAsm blocks are compiled on program load and their entry points are fitted into the framework of an ordinary internal variant-based tree of a user defined function. There is no "external" difference between the tree (i.e. a doubly linked list of arguments, entry and return addresses, and a variant that would store persistently the most recent return value of this function) of an ordinary user defined BASIC function and a function precompiled by any of the two JITs. And the only "internal" difference between them would be that an interpretative BASIC function would make sideways calls to the virtual machine's helper routines to perform its duties while a JIT function would be completely self-sufficient -- sort of "encapsulated".
That said, FBSL would always create an invisible GUI window on launching regardless of the script's
#apptype. If the #apptype is
GUI (the default) or
MDI, the user is supposed to optionally resize and center or otherwise reshape the window to the program's needs, show it and fall through to the Begin Events/End Events block which is a prettified callback for processing the window's messages.
The console is not automatically created in a GUI application. It is created on the fly only if the script hits an unsuppressed warning or untrapped error condition, in which case the console is immediately spawned through the same AllocConsole() and associated text coloration helpers to serve as an stderr device.
In an
#apptype console or
cgi mode, the console is created automatically via AllocConsole() at app start while the GUI window stays hidden at all times. This is the device where BASIC, C, and Asm code prints to, if needed, utilizing any of the BASIC or C or asm facilities that the programmer wishes, including BASIC PRINTF() and its derivatives, C fprintf() or printf(), or asm calls to any libraries preloaded for that purpose.
Printing occurs automagically: once the process has its console window opened, all printing goes there all by itself regardless of what printing functions are invoked.
If gxo2.exe acts in the same manner, i.e. if JIT compiled code runs within the bounds of gxo2's process as a subroutine, then gxo2.exe should spawn its own console in response to the
#console directive in the script. But if it emits precompiled O2 code as a separate process, it should then inject transparently the AllocConsole() lines into the script just before compilation in response to the #console directive.
I hope my explanations are helpful.