I'm trying to embed gambit in a Qt-based Windows application (compiled with MinGW). The app works fine when I link to Qt as a console application. However, when I removed the -console option from Qt and rebuilt the app, first it died in ___device_pipe_close_raw_virt on the CloseHandle call (around line 2710 of os_io.c). After searching the mailing list, I figured this was because it was trying to close stdin/stdout/stderr there. So I put in a check to see if d->h_wr was equal to those handles. That got me past that point. Then the application would startup, then exit without error. After debugging it in gdb, I realized it was running the ___winmain function from os_base.c and then exiting.
So I'm wondering -- has Gambit ever been tested to work without the console window? I know you can hide it when calling the process-related procedures, but I couldn't find anything in the documentation or on the mailing list about the main app not having a console.
The people using the application I'm writing definitely don't want a console window popping up when it is started, so I'd really like to get rid of it.
I suspect that I need to somehow link in libgamb.a without it having a WinMain function (since that is the Windows application's "main" function). Obviously, the Qt side has its own WinMain. I'm a little surprised that there wasn't a linking error there due to multiple WinMain functions, but I haven't investigated that yet.
Anyway, any hints anyone can give me on how to get this working would be greatly appreciated. I'm hoping that others have done this before and there is something simple that I've missed. Oh, btw, I'm doing all of this using version 4.6.4.
Afficher les réponses par date
On 2012-04-09, at 9:44 AM, REPLeffect wrote:
So I'm wondering -- has Gambit ever been tested to work without the console window? I know you can hide it when calling the process-related procedures, but I couldn't find anything in the documentation or on the mailing list about the main app not having a console.
It is clearly possible, for example the Jedi IDE for JazzScheme is a window application written with Gambit. Perhaps looking at the Jedi sources will give you some ideas.
Also, here's an old message to the Gambit ML which seems related :
https://mercure.iro.umontreal.ca/pipermail/gambit-list/2011-March/004939.htm...
Finally, I sent a private message on this subject which I should have CC'd to the Gambit ML. It is copied below.
Let me know if you need more assistance.
Marc
Begin forwarded message:
From: Marc Feeley feeley@iro.umontreal.ca Subject: Re: [gambit-list] Gambit-C and cygwin Date: 20 March, 2011 2:29:57 PM EDT To: Valeriya Pudova valery@digitalchile.net Cc: Mikael More mikael.more@gmail.com
On 2011-03-20, at 12:46 PM, Valeriya Pudova wrote:
Hello Mikael,
Thanks for your note. That is right. But gsc should add the (main) code to .c file. Is it not?
For portability it is a bit more complicated than that. A typical Unix application has a "main" function which is the entry point of the program. On Windows, for a graphical Windows-based application, the entry point is "WinMain". On the other hand, for a library of code, there is no entry function.
When you compile a Scheme program "foo.scm" with
gsc -link foo.scm
the Gambit compiler will generate two files:
foo.c compilation of foo.scm to C foo_.c the "link file" which contains initialization code for linking foo.c to the Gambit runtime library
The link file contains code to define a "main" or "WinMain" function (when an entry function is required). The function "WinMain" will be defined if the symbol _WINDOWS is defined, otherwise the function "main" will be defined. These entry functions call functions in the Gambit runtime to process the command-line arguments, initialize the runtime system, and start the execution of the Scheme program. The definition of these entry functions is conditional. When the symbol ___LIBRARY is defined (usually on the C compiler command line) then no entry function will be defined. This is useful for libraries.
Also, I need a console application, and believe that gsc should make this type of application by default.
It should! Perhaps you have mingw and cygwin installed on the same machine and when you call "gcc" it uses the wrong compiler (and I think the mingw gcc defines _WINDOWS by default). Just a guess. I remember some time ago that someone suggested using a flag line "gcc -mno-mingw" or something to prevent this problem. I'm not a Windows expert, so you need to dig for this yourself to verify.
Is it not? BTW Which of the gsc's or gambc-cc.bat's arguments change the type of app. console | win ?
It is a question of whether _WINDOWS is defined when the link file is compiled by the C compiler.
Marc
On Mon, Apr 9, 2012 at 9:16 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-04-09, at 9:44 AM, REPLeffect wrote:
So I'm wondering -- has Gambit ever been tested to work without the console window? I know you can hide it when calling the process-related procedures, but I couldn't find anything in the documentation or on the mailing list about the main app not having a console.
It is clearly possible, for example the Jedi IDE for JazzScheme is a window application written with Gambit. Perhaps looking at the Jedi sources will give you some ideas.
Also, here's an old message to the Gambit ML which seems related :
https://mercure.iro.umontreal.ca/pipermail/gambit-list/2011-March/004939.htm...
Finally, I sent a private message on this subject which I should have CC'd to the Gambit ML. It is copied below.
Let me know if you need more assistance.
Marc
[snip]
Thank you, Marc. That was very helpful. Turns out, I was not defining ___LIBRARY while compiling one of my scheme modules, nor when compiling at least one of the link files I was generating.
After adding the ___LIBRARY define, the application ran fine when compiled as a non-console windows app. I even checked the portable executable header of the executable to confirm that it was using the "windows" subsystem (as opposed to "console") -- which it was.
The only thing that puzzled me, was that I was still getting a terminal window popping up with my debug messages printed to standard output. On a hunch, I ran the executable and piped stdout to an output file. When I did this, no console window popped up, and the application ran as expected.
So my question is this -- If a Windows app with Gambit embedded does not have a console, does the runtime open a new one (using CreateProcesss, I'm assuming) in order to display data sent to stdout? And if so, are there any setup parameters I can change to prevent this? Ideally I'd like to be able to turn this on and off at will, or at least be able to chose one way or another at startup. For debugging purposes, it is handy to have the console, but for my users I'd want to shut it off.
Thanks again for the help.
On 2012-04-09, at 12:59 PM, REPLeffect wrote:
On Mon, Apr 9, 2012 at 9:16 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-04-09, at 9:44 AM, REPLeffect wrote:
So I'm wondering -- has Gambit ever been tested to work without the console window? I know you can hide it when calling the process-related procedures, but I couldn't find anything in the documentation or on the mailing list about the main app not having a console.
It is clearly possible, for example the Jedi IDE for JazzScheme is a window application written with Gambit. Perhaps looking at the Jedi sources will give you some ideas.
Also, here's an old message to the Gambit ML which seems related :
https://mercure.iro.umontreal.ca/pipermail/gambit-list/2011-March/004939.htm...
Finally, I sent a private message on this subject which I should have CC'd to the Gambit ML. It is copied below.
Let me know if you need more assistance.
Marc
[snip]
Thank you, Marc. That was very helpful. Turns out, I was not defining ___LIBRARY while compiling one of my scheme modules, nor when compiling at least one of the link files I was generating.
After adding the ___LIBRARY define, the application ran fine when compiled as a non-console windows app. I even checked the portable executable header of the executable to confirm that it was using the "windows" subsystem (as opposed to "console") -- which it was.
The only thing that puzzled me, was that I was still getting a terminal window popping up with my debug messages printed to standard output. On a hunch, I ran the executable and piped stdout to an output file. When I did this, no console window popped up, and the application ran as expected.
So my question is this -- If a Windows app with Gambit embedded does not have a console, does the runtime open a new one (using CreateProcesss, I'm assuming) in order to display data sent to stdout? And if so, are there any setup parameters I can change to prevent this? Ideally I'd like to be able to turn this on and off at will, or at least be able to chose one way or another at startup. For debugging purposes, it is handy to have the console, but for my users I'd want to shut it off.
On Windows, the console is actually created by a call to AllocConsole in lib/os_tty.c (on Unix, the "controlling terminal" is opened). This is done lazily upon the first output (or input) to the "console port" (which is the port returned by the procedure console-port). The console port is the port normally attached to the REPL channel. So the console will pop up when an error message needs to be output, or when pp is called (with no explicit port argument), or when a REPL is started for any of many reasons.
The REPL channel's port can be changed by adding the -:d- runtime option when the program is started. This will assign the standard input/output to the REPL channel. For example :
% gsi -e "(/ 1 0)" > out *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0) % cat out % gsi -:d- -e "(/ 1 0)" > out % cat out *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0)
Moreover, by adding a 0 to the runtime debug options, the display of the error message will be supressed:
% gsi -:d0- -e "(/ 1 0)" % echo $? 70 % gsi -:d- -e "(/ 1 0)" *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0)
Note also that you can write a script whose first line contains the runtime options. For example, on Unix:
-------------------------------------------- #! /usr/bin/gsi -:d0- (pp (/ 1 0)) --------------------------------------------
or on Windows:
-------------------------------------------- @; gsi.exe -:d0- (pp (/ 1 0)) --------------------------------------------
Finally, note that the runtime options on the first line of a script that is compiled by gsc become the *default* runtime options when they are not specified explicitly to the executable.
This is probably what you should do to avoid creating a console window.
You might want to read the "Compiling scripts" section of the Gambit manual.
Marc
On Mon, Apr 9, 2012 at 12:52 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-04-09, at 12:59 PM, REPLeffect wrote:
On Mon, Apr 9, 2012 at 9:16 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-04-09, at 9:44 AM, REPLeffect wrote:
So I'm wondering -- has Gambit ever been tested to work without the console window? I know you can hide it when calling the process-related procedures, but I couldn't find anything in the documentation or on the mailing list about the main app not having a console.
It is clearly possible, for example the Jedi IDE for JazzScheme is a window application written with Gambit. Perhaps looking at the Jedi sources will give you some ideas.
Also, here's an old message to the Gambit ML which seems related :
https://mercure.iro.umontreal.ca/pipermail/gambit-list/2011-March/004939.htm...
Finally, I sent a private message on this subject which I should have CC'd to the Gambit ML. It is copied below.
Let me know if you need more assistance.
Marc
[snip]
Thank you, Marc. That was very helpful. Turns out, I was not defining ___LIBRARY while compiling one of my scheme modules, nor when compiling at least one of the link files I was generating.
After adding the ___LIBRARY define, the application ran fine when compiled as a non-console windows app. I even checked the portable executable header of the executable to confirm that it was using the "windows" subsystem (as opposed to "console") -- which it was.
The only thing that puzzled me, was that I was still getting a terminal window popping up with my debug messages printed to standard output. On a hunch, I ran the executable and piped stdout to an output file. When I did this, no console window popped up, and the application ran as expected.
So my question is this -- If a Windows app with Gambit embedded does not have a console, does the runtime open a new one (using CreateProcesss, I'm assuming) in order to display data sent to stdout? And if so, are there any setup parameters I can change to prevent this? Ideally I'd like to be able to turn this on and off at will, or at least be able to chose one way or another at startup. For debugging purposes, it is handy to have the console, but for my users I'd want to shut it off.
On Windows, the console is actually created by a call to AllocConsole in lib/os_tty.c (on Unix, the "controlling terminal" is opened). This is done lazily upon the first output (or input) to the "console port" (which is the port returned by the procedure console-port). The console port is the port normally attached to the REPL channel. So the console will pop up when an error message needs to be output, or when pp is called (with no explicit port argument), or when a REPL is started for any of many reasons.
Funny -- just before I saw this reply I had been poking around in os_tty.c and discovered this. I figured this would be the key to getting the behavior I was looking for.
The REPL channel's port can be changed by adding the -:d- runtime option when the program is started. This will assign the standard input/output to the REPL channel. For example :
% gsi -e "(/ 1 0)" > out *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0) % cat out % gsi -:d- -e "(/ 1 0)" > out % cat out *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0)
Moreover, by adding a 0 to the runtime debug options, the display of the error message will be supressed:
% gsi -:d0- -e "(/ 1 0)" % echo $? 70 % gsi -:d- -e "(/ 1 0)" *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0)
[snip]
I had already been running my app with -:d-, but somehow missed -:d0 -- that almost gives me what I want (by suppressing the error messages). However, I have some messages in my app that are being sent to stdout, and even with -:d0, the console is still being shown by these. Of course, the AllocConsole call is the culprit.
This led me to doing some experimentation. I tried calling AllocConsole before creating the main Qt window of my application, but that made the console pop up immediately (which is what I was trying to avoid). Then I decided to cheat it a little, and use CreateProcess to restart my app with the creation flags set to CREAecTE_NEW_CONSOLE|CREATE_NO_WINDOW -- then once the app was loaded, I caused it to show its main window. That worked fine, but I wasn't satisfied with it, because I was having to start two processes to start up the app.
Finally, it occurred to me that I should try to first create the main window, but not show it, then call AllocConsole while the main window is hidden, and then show the main window. This did exactly what I wanted. The console is created, but it is hidden from the users view. As a side benefit, if you start the application from a command shell (cmd.exe), or from a MSYS or cygwin terminal (rxvt or mintty), you get the console output. In the case of cmd.exe, a new console window is opened which displays the output. In the case of rxvt and mintty, the output is displayed in the terminal itself.
This is precisely the behavior I was looking for.
On Tue, Apr 10, 2012 at 2:13 PM, REPLeffect repleffect@gmail.com wrote:
On Mon, Apr 9, 2012 at 12:52 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-04-09, at 12:59 PM, REPLeffect wrote:
On Mon, Apr 9, 2012 at 9:16 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-04-09, at 9:44 AM, REPLeffect wrote:
So I'm wondering -- has Gambit ever been tested to work without the console window? I know you can hide it when calling the process-related procedures, but I couldn't find anything in the documentation or on the mailing list about the main app not having a console.
It is clearly possible, for example the Jedi IDE for JazzScheme is a window application written with Gambit. Perhaps looking at the Jedi sources will give you some ideas.
Also, here's an old message to the Gambit ML which seems related :
https://mercure.iro.umontreal.ca/pipermail/gambit-list/2011-March/004939.htm...
Finally, I sent a private message on this subject which I should have CC'd to the Gambit ML. It is copied below.
Let me know if you need more assistance.
Marc
[snip]
Thank you, Marc. That was very helpful. Turns out, I was not defining ___LIBRARY while compiling one of my scheme modules, nor when compiling at least one of the link files I was generating.
After adding the ___LIBRARY define, the application ran fine when compiled as a non-console windows app. I even checked the portable executable header of the executable to confirm that it was using the "windows" subsystem (as opposed to "console") -- which it was.
The only thing that puzzled me, was that I was still getting a terminal window popping up with my debug messages printed to standard output. On a hunch, I ran the executable and piped stdout to an output file. When I did this, no console window popped up, and the application ran as expected.
So my question is this -- If a Windows app with Gambit embedded does not have a console, does the runtime open a new one (using CreateProcesss, I'm assuming) in order to display data sent to stdout? And if so, are there any setup parameters I can change to prevent this? Ideally I'd like to be able to turn this on and off at will, or at least be able to chose one way or another at startup. For debugging purposes, it is handy to have the console, but for my users I'd want to shut it off.
On Windows, the console is actually created by a call to AllocConsole in lib/os_tty.c (on Unix, the "controlling terminal" is opened). This is done lazily upon the first output (or input) to the "console port" (which is the port returned by the procedure console-port). The console port is the port normally attached to the REPL channel. So the console will pop up when an error message needs to be output, or when pp is called (with no explicit port argument), or when a REPL is started for any of many reasons.
Funny -- just before I saw this reply I had been poking around in os_tty.c and discovered this. I figured this would be the key to getting the behavior I was looking for.
The REPL channel's port can be changed by adding the -:d- runtime option when the program is started. This will assign the standard input/output to the REPL channel. For example :
% gsi -e "(/ 1 0)" > out *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0) % cat out % gsi -:d- -e "(/ 1 0)" > out % cat out *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0)
Moreover, by adding a 0 to the runtime debug options, the display of the error message will be supressed:
% gsi -:d0- -e "(/ 1 0)" % echo $? 70 % gsi -:d- -e "(/ 1 0)" *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0)
[snip]
I had already been running my app with -:d-, but somehow missed -:d0 -- that almost gives me what I want (by suppressing the error messages). However, I have some messages in my app that are being sent to stdout, and even with -:d0, the console is still being shown by these. Of course, the AllocConsole call is the culprit.
This led me to doing some experimentation. I tried calling AllocConsole before creating the main Qt window of my application, but that made the console pop up immediately (which is what I was trying to avoid). Then I decided to cheat it a little, and use CreateProcess to restart my app with the creation flags set to CREAecTE_NEW_CONSOLE|CREATE_NO_WINDOW -- then once the app was loaded, I caused it to show its main window. That worked fine, but I wasn't satisfied with it, because I was having to start two processes to start up the app.
Finally, it occurred to me that I should try to first create the main window, but not show it, then call AllocConsole while the main window is hidden, and then show the main window. This did exactly what I wanted. The console is created, but it is hidden from the users view. As a side benefit, if you start the application from a command shell (cmd.exe), or from a MSYS or cygwin terminal (rxvt or mintty), you get the console output. In the case of cmd.exe, a new console window is opened which displays the output. In the case of rxvt and mintty, the output is displayed in the terminal itself.
This is precisely the behavior I was looking for.
AARGGHHHH!!!
After all of that, looks like my final solution is totally bogus. I forgot to change the desktop shortcut I was using to test AllocConsole on a hidden main window. Contrary to what I thought, I was *still* using the two-process method to start up the app. After pointing the shortcut to the correct executable, the console still shows up when AllocConsole is called (even if the main window is still hidden). Ah, well, at least I have an only slightly-lame solution.
Dear REPLeffect,
Windows EXE:s are hardwired to either be console or UI apps.
By default, Gambit produces EXE:s that are console apps.
UI app means, don't create a console window unless any console IO is made by the app, and if that is made, then a _new_ console window is opened.
Console app means, that if the app is executed within a console already, then it'll use that console, and if it's not, a new console will be created for it.
This is how Windows is hardwired as regards console windows.
To see how to produce an UI app, which is what you want, see the "How to build GUI apps for Win32 " section at http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Compiling_Gambit_softw....
It summarizes as: The key recipe in here is to pass -D_WINDOWS to cl.exe, and /subsystem:windows to link.exe .
Was this of help to you?
Kind regards, Mikael
Den 10 april 2012 22:42 skrev REPLeffect repleffect@gmail.com:
On Tue, Apr 10, 2012 at 2:13 PM, REPLeffect repleffect@gmail.com wrote:
On Mon, Apr 9, 2012 at 12:52 PM, Marc Feeley feeley@iro.umontreal.ca
wrote:
On 2012-04-09, at 12:59 PM, REPLeffect wrote:
On Mon, Apr 9, 2012 at 9:16 AM, Marc Feeley feeley@iro.umontreal.ca
wrote:
On 2012-04-09, at 9:44 AM, REPLeffect wrote:
So I'm wondering -- has Gambit ever been tested to work without the console window? I know you can hide it when calling the process-related procedures, but I couldn't find anything in the documentation or on the mailing list about the main app not having a console.
It is clearly possible, for example the Jedi IDE for JazzScheme is a
window application written with Gambit. Perhaps looking at the Jedi sources will give you some ideas.
Also, here's an old message to the Gambit ML which seems related :
https://mercure.iro.umontreal.ca/pipermail/gambit-list/2011-March/004939.htm...
Finally, I sent a private message on this subject which I should have
CC'd to the Gambit ML. It is copied below.
Let me know if you need more assistance.
Marc
[snip]
Thank you, Marc. That was very helpful. Turns out, I was not defining ___LIBRARY while compiling one of my scheme modules, nor when compiling at least one of the link files I was generating.
After adding the ___LIBRARY define, the application ran fine when compiled as a non-console windows app. I even checked the portable executable header of the executable to confirm that it was using the "windows" subsystem (as opposed to "console") -- which it was.
The only thing that puzzled me, was that I was still getting a terminal window popping up with my debug messages printed to standard output. On a hunch, I ran the executable and piped stdout to an output file. When I did this, no console window popped up, and the application ran as expected.
So my question is this -- If a Windows app with Gambit embedded does not have a console, does the runtime open a new one (using CreateProcesss, I'm assuming) in order to display data sent to stdout? And if so, are there any setup parameters I can change to prevent this? Ideally I'd like to be able to turn this on and off at will, or at least be able to chose one way or another at startup. For debugging purposes, it is handy to have the console, but for my users I'd want to shut it off.
On Windows, the console is actually created by a call to AllocConsole
in lib/os_tty.c (on Unix, the "controlling terminal" is opened). This is done lazily upon the first output (or input) to the "console port" (which is the port returned by the procedure console-port). The console port is the port normally attached to the REPL channel. So the console will pop up when an error message needs to be output, or when pp is called (with no explicit port argument), or when a REPL is started for any of many reasons.
Funny -- just before I saw this reply I had been poking around in os_tty.c and discovered this. I figured this would be the key to getting the behavior I was looking for.
The REPL channel's port can be changed by adding the -:d- runtime
option when the program is started. This will assign the standard input/output to the REPL channel. For example :
% gsi -e "(/ 1 0)" > out *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0) % cat out % gsi -:d- -e "(/ 1 0)" > out % cat out *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0)
Moreover, by adding a 0 to the runtime debug options, the display of
the error message will be supressed:
% gsi -:d0- -e "(/ 1 0)" % echo $? 70 % gsi -:d- -e "(/ 1 0)" *** ERROR IN (string)@1.1 -- Divide by zero (/ 1 0)
[snip]
I had already been running my app with -:d-, but somehow missed -:d0 -- that almost gives me what I want (by suppressing the error messages). However, I have some messages in my app that are being sent to stdout, and even with -:d0, the console is still being shown by these. Of course, the AllocConsole call is the culprit.
This led me to doing some experimentation. I tried calling AllocConsole before creating the main Qt window of my application, but that made the console pop up immediately (which is what I was trying to avoid). Then I decided to cheat it a little, and use CreateProcess to restart my app with the creation flags set to CREAecTE_NEW_CONSOLE|CREATE_NO_WINDOW -- then once the app was loaded, I caused it to show its main window. That worked fine, but I wasn't satisfied with it, because I was having to start two processes to start up the app.
Finally, it occurred to me that I should try to first create the main window, but not show it, then call AllocConsole while the main window is hidden, and then show the main window. This did exactly what I wanted. The console is created, but it is hidden from the users view. As a side benefit, if you start the application from a command shell (cmd.exe), or from a MSYS or cygwin terminal (rxvt or mintty), you get the console output. In the case of cmd.exe, a new console window is opened which displays the output. In the case of rxvt and mintty, the output is displayed in the terminal itself.
This is precisely the behavior I was looking for.
AARGGHHHH!!!
After all of that, looks like my final solution is totally bogus. I forgot to change the desktop shortcut I was using to test AllocConsole on a hidden main window. Contrary to what I thought, I was *still* using the two-process method to start up the app. After pointing the shortcut to the correct executable, the console still shows up when AllocConsole is called (even if the main window is still hidden). Ah, well, at least I have an only slightly-lame solution. _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
On Tue, Apr 10, 2012 at 2:46 PM, Mikael mikael.rcv@gmail.com wrote:
Dear REPLeffect,
Windows EXE:s are hardwired to either be console or UI apps.
^ I'm well aware of that. Perhaps you missed the earlier message where I said this:
After adding the ___LIBRARY define, the application ran fine when compiled as a non-console windows app. I even checked the portable executable header of the executable to confirm that it was using the "windows" subsystem (as opposed to "console") -- which it was.
The portable executable header in Windows applications has a "Subsystem" field in it that determines whether an app is a console app or a standard windows GUI app.
Here's an article discussing the PE header, for anyone who is interested.
http://msdn.microsoft.com/en-us/library/ms809762.aspx
By default, Gambit produces EXE:s that are console apps.
^^ That should be true of applications compiled and linked using gsc (as Marc pointed out in the message to you that he quoted in his first response to this thread). However, as you might guess from the above quote from my previous post, I'm compiling and linking modules separately. I'm embedding Gambit Scheme in a C++ executable (initializing a ___setup_params_struct structure, then calling ___setup, etc). My final link is actually being done by a qmake-generated makefile, and the windows subsystem is being set by the link performed from there. I'd already dealt with the subsystem change before posting my original question.
UI app means, don't create a console window unless any console IO is made by the app, and if that is made, then a _new_ console window is opened.
Console app means, that if the app is executed within a console already, then it'll use that console, and if it's not, a new console will be created for it.
At this point I'm sure you realize that I already knew the difference between console and non-console apps in Windows (as well as the fact that standard GUI apps have the ability to create a console).
When I asked the original question, I was more wondering how much Gambit had been used for GUI applications which did not have a console at all -- that is, "windows" subsystem apps which also don't create a console separately (as they can, with AllocConsole, but obviously most GUI apps usually don't).
I probably should not have brought up the discussion about WinMain the way I did -- it is a separate piece of the puzzle, and I probably confused the issue by doing so. Then again, it was related to the problem of missing ___LIBRARY defines in one place in my build, so I guess I'm glad I brought it up anyway. :-D
This is how Windows is hardwired as regards console windows.
To see how to produce an UI app, which is what you want, see the "How to build GUI apps for Win32 " section at http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Compiling_Gambit_softw...
It summarizes as: The key recipe in here is to pass -D_WINDOWS to cl.exe, and /subsystem:windows to link.exe .
Was this of help to you?
The wiki entry is a good link to point to when discussing this, just a little late in the conversation (since both the subsystem and the _WINDOWS macro have already been discussed) :-D
Also, as I mentioned in the original post, I'm not using Visual C++, I'm compiling with g++ under MinGW. For g++ you have to add the subsystem selection to the link flags like this:
-Wl,-subsystem,windows
For now I'll probably just stick with the CreateProcess solution, and look for something more elegant at a later date. Would be nice if AllocConsole in a GUI app allowed you to create the console hidden, but its obvious that the use case I'm looking for isn't something that Microsoft was trying to provide when they designed the console API.
On 2012-04-10, at 3:13 PM, REPLeffect wrote:
I had already been running my app with -:d-, but somehow missed -:d0 -- that almost gives me what I want (by suppressing the error messages). However, I have some messages in my app that are being sent to stdout, and even with -:d0, the console is still being shown by these. Of course, the AllocConsole call is the culprit.
Can you explain this a bit more. I don't understand why the output would go to the console if you write to stdout. Can you verify that this is the case? Note that the pp procedure defaults to writing to the REPL port.
Note that if you want to ignore all output sent to the current-output-port, you could simply do this:
(current-output-port (open-dummy))
Marc
On Tue, Apr 10, 2012 at 5:37 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-04-10, at 3:13 PM, REPLeffect wrote:
I had already been running my app with -:d-, but somehow missed -:d0 -- that almost gives me what I want (by suppressing the error messages). However, I have some messages in my app that are being sent to stdout, and even with -:d0, the console is still being shown by these. Of course, the AllocConsole call is the culprit.
Can you explain this a bit more. I don't understand why the output would go to the console if you write to stdout. Can you verify that this is the case? Note that the pp procedure defaults to writing to the REPL port.
I am actually using println (not pp) in the messages that are causing the console to open.
I was able to reproduce the problem by modifying Mikael's MessageBox example. This version opens the message box, then once the message box is closed, it prints to stdout once each second for 10 seconds:
(c-declare "#include <windows.h>") (define message-box (c-lambda (UTF-8-string) void "MessageBox(0,___arg1,"Dbg",0);")) (message-box "Hi!") (let loop ((count 0)) (println "test stdout") (thread-sleep! 1) (if (< count 10) (loop (+ count 1))))
I saved that as test.scm, and compiled it under MinGW like this:
gsc -link test.scm
g++ -c -I"C:/Gambit-C/include" -I"C:/Gambit-C/lib" -D___SINGLE_HOST -D_WINDOWS test_.c test.c
g++ -mthreads -Wl,-subsystem,windows -o test.exe test.o test_.o -LC:/Gambit-C/lib -lgambc -L. -lkernel32 -luser32 -lgdi32 -lmingw32 -lws2_32
When I run test.exe, the message box appears, then I click 'OK' and the console appears, displaying the line "test stdout" 10 times (once per second).
Note that if you want to ignore all output sent to the current-output-port, you could simply do this:
(current-output-port (open-dummy))
^^ That actually works beautifully. open-dummy could come in very handy. Thanks! If I can't figure out a better solution, that's what I'll do.
Let me know if you want me to test anything further.
On Wed, Apr 11, 2012 at 5:46 PM, REPLeffect repleffect@gmail.com wrote:
On Tue, Apr 10, 2012 at 5:37 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-04-10, at 3:13 PM, REPLeffect wrote:
I had already been running my app with -:d-, but somehow missed -:d0 -- that almost gives me what I want (by suppressing the error messages). However, I have some messages in my app that are being sent to stdout, and even with -:d0, the console is still being shown by these. Of course, the AllocConsole call is the culprit.
Can you explain this a bit more. I don't understand why the output would go to the console if you write to stdout. Can you verify that this is the case? Note that the pp procedure defaults to writing to the REPL port.
I am actually using println (not pp) in the messages that are causing the console to open.
I was able to reproduce the problem by modifying Mikael's MessageBox example. This version opens the message box, then once the message box is closed, it prints to stdout once each second for 10 seconds:
(c-declare "#include <windows.h>") (define message-box (c-lambda (UTF-8-string) void "MessageBox(0,___arg1,"Dbg",0);")) (message-box "Hi!") (let loop ((count 0)) (println "test stdout") (thread-sleep! 1) (if (< count 10) (loop (+ count 1))))
I saved that as test.scm, and compiled it under MinGW like this:
gsc -link test.scm
g++ -c -I"C:/Gambit-C/include" -I"C:/Gambit-C/lib" -D___SINGLE_HOST -D_WINDOWS test_.c test.c
g++ -mthreads -Wl,-subsystem,windows -o test.exe test.o test_.o -LC:/Gambit-C/lib -lgambc -L. -lkernel32 -luser32 -lgdi32 -lmingw32 -lws2_32
When I run test.exe, the message box appears, then I click 'OK' and the console appears, displaying the line "test stdout" 10 times (once per second).
I just double-checked this by having the test program print out the value of (current-output-port), changing this line:
(println "test stdout:")
to this:
(println "test stdout: " (current-output-port))
And the resulting output was this:
test stdout: #<output-port #2 (stdout)>
(repeated 9 other times, of course).
On 2012-04-11, at 6:46 PM, REPLeffect wrote:
On Tue, Apr 10, 2012 at 5:37 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-04-10, at 3:13 PM, REPLeffect wrote:
I had already been running my app with -:d-, but somehow missed -:d0 -- that almost gives me what I want (by suppressing the error messages). However, I have some messages in my app that are being sent to stdout, and even with -:d0, the console is still being shown by these. Of course, the AllocConsole call is the culprit.
Can you explain this a bit more. I don't understand why the output would go to the console if you write to stdout. Can you verify that this is the case? Note that the pp procedure defaults to writing to the REPL port.
I am actually using println (not pp) in the messages that are causing the console to open.
I was able to reproduce the problem by modifying Mikael's MessageBox example. This version opens the message box, then once the message box is closed, it prints to stdout once each second for 10 seconds:
(c-declare "#include <windows.h>") (define message-box (c-lambda (UTF-8-string) void "MessageBox(0,___arg1,"Dbg",0);")) (message-box "Hi!") (let loop ((count 0)) (println "test stdout") (thread-sleep! 1) (if (< count 10) (loop (+ count 1))))
I saved that as test.scm, and compiled it under MinGW like this:
gsc -link test.scm
g++ -c -I"C:/Gambit-C/include" -I"C:/Gambit-C/lib" -D___SINGLE_HOST -D_WINDOWS test_.c test.c
g++ -mthreads -Wl,-subsystem,windows -o test.exe test.o test_.o -LC:/Gambit-C/lib -lgambc -L. -lkernel32 -luser32 -lgdi32 -lmingw32 -lws2_32
When I run test.exe, the message box appears, then I click 'OK' and the console appears, displaying the line "test stdout" 10 times (once per second).
To simplify the build steps I built your test program 2 ways, as a "console" application and a "windows" application:
1) gsc -exe test.scm
2) gsc -exe -ld-options "-Wl,-subsystem,windows" test.scm
When I do
./test > out
the dialog is shown and the output "test stdout" goes to the file "out" in both cases.
When I have no redirection of stdout, i.e.:
./test
then after the dialog is dismissed, the "console" version outputs "test stdout" to the console from which the program was started, and the "windows" version opens a new console for writing the output.
I believe the difference in this case is due to the way Windows assigns a "console" to a program when it is started (i.e. whether it is a "console" application or a "windows" application). If I recall correctly, "windows" applications aren't assigned a console when they are started and they don't have a default stdin/stdout.
My question is this: is it important that your application be a "windows" application? What are the benefits over a "console" application.
In any case, since you are not interested in the output to the current output port, this difference can be eliminated by assigning a dummy port to the current output port.
Marc
Den 12 april 2012 23:44 skrev Marc Feeley feeley@iro.umontreal.ca:
My question is this: is it important that your application be a "windows" application? What are the benefits over a "console" application.
"console" applications are good for apps where you have a practical use of the app being hardwired to the presence of a console window only. So it's a nice default setting for developers, to have a console to print out to, take text input, and so on.
The issue is just that "console" applications, if launched not from a console (but from, say, Explorer), get a console window allocated to them at startup, even if there is no console IO.
If you want to make an UI app (for example, an alarm clock), obviously you want your users' experience to be about your UI only, and a console window popping up in the background would be quiet shocking for them.
In console apps, you can deallocate the console I think, but even then it flashes by quickly on the screen, giving the user a feeling that something is not right.
So the most straightforward thing for gui apps is to be compiled as "windows" application, and then to not use any console io at all (so, no access to current-output-port etc. at all, not even a (force-output) to it), because on such use a console window would be dynamically allocated anyhow. (There's some way to deallocate it just like above, though of course then it'd flash by at least just like above.) REPLeffect ought to have had some routine in his app that did that, and this is why the dynamic console window allocation he experienced was remedied by your suggestion of overwriting current-output-port with a dummy port..
Not completely obvious abstraction this console vs. windows application thing. How is it in Unix, GUI apps have their own stdin/out completely decoupled from the GUI workings, and generally it's piped to the app's console which may be the host terminal window of the X server, or /dev/null, sth like this.
Brgds
(Ah, there's even more to it btw, if you make a "windows" application and launch it from a console application, and then in that "windows" application you make actually performs console I/O operations, then a new console window is (dynamically) allocated for that IO i.e. it opens on top of the parent console window.)
On 2012-04-12, at 5:08 PM, Mikael wrote:
(Ah, there's even more to it btw, if you make a "windows" application and launch it from a console application, and then in that "windows" application you make actually performs console I/O operations, then a new console window is (dynamically) allocated for that IO i.e. it opens on top of the parent console window.)
Is there a natural "standard input/output" for windows applications? If there is, then Gambit should not redirect them to the newly allocated console. However, if there isn't as I think is the case, then it makes sense to redirect standard input/output to it, as is the case now.
Marc
Correct I think.
Den 13 april 2012 00:40 skrev Marc Feeley feeley@iro.umontreal.ca:
On 2012-04-12, at 5:08 PM, Mikael wrote:
(Ah, there's even more to it btw, if you make a "windows" application
and launch it from a console application, and then in that "windows" application you make actually performs console I/O operations, then a new console window is (dynamically) allocated for that IO i.e. it opens on top of the parent console window.)
Is there a natural "standard input/output" for windows applications? If there is, then Gambit should not redirect them to the newly allocated console.
However, if there isn't as I think is the case, then it makes sense to redirect standard input/output to it, as is the case now.
^
Marc
On Thu, Apr 12, 2012 at 4:40 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
On 2012-04-12, at 5:08 PM, Mikael wrote:
(Ah, there's even more to it btw, if you make a "windows" application and launch it from a console application, and then in that "windows" application you make actually performs console I/O operations, then a new console window is (dynamically) allocated for that IO i.e. it opens on top of the parent console window.)
Is there a natural "standard input/output" for windows applications? If there is, then Gambit should not redirect them to the newly allocated console. However, if there isn't as I think is the case, then it makes sense to redirect standard input/output to it, as is the case now.
As Mikael rightly pointed out, no. stdin is basically meaningless, and output to stdout and stderr goes to the bitbucket normally under Windows GUI apps. I say just add it to the long list of things that work better under Unix/Linux-style operating systems. Unfortunately most of us who make our living dealing with computers still have to deal with Windows.
Well, at least I don't have to write COBOL for a living :-D
REPLeffect
On Thu, Apr 12, 2012 at 4:05 PM, Mikael mikael.rcv@gmail.com wrote:
Den 12 april 2012 23:44 skrev Marc Feeley feeley@iro.umontreal.ca:
My question is this: is it important that your application be a "windows" application? What are the benefits over a "console" application.
"console" applications are good for apps where you have a practical use of the app being hardwired to the presence of a console window only. So it's a nice default setting for developers, to have a console to print out to, take text input, and so on.
The issue is just that "console" applications, if launched not from a console (but from, say, Explorer), get a console window allocated to them at startup, even if there is no console IO.
If you want to make an UI app (for example, an alarm clock), obviously you want your users' experience to be about your UI only, and a console window popping up in the background would be quiet shocking for them.
^^ This is indeed the reason why my app has to be a windows app. The users would complain if a console window appears when the app is run (they would probably interpret that to mean something was wrong :-D ).
In console apps, you can deallocate the console I think, but even then it flashes by quickly on the screen, giving the user a feeling that something is not right.
Yes, one solution would be to use GetConsoleWindow() and hide the window immediately after calling AllocConsole() and then hide the window. But, again the users wouldn't like the flashing window any better.
So the most straightforward thing for gui apps is to be compiled as "windows" application, and then to not use any console io at all (so, no access to current-output-port etc. at all, not even a (force-output) to it), because on such use a console window would be dynamically allocated anyhow. (There's some way to deallocate it just like above, though of course then it'd flash by at least just like above.) REPLeffect ought to have had some routine in his app that did that, and this is why the dynamic console window allocation he experienced was remedied by your suggestion of overwriting current-output-port with a dummy port..
Yes, one possible solution is to not print to stdout or stderr at all, but rather have some other facility for logging debugging messages. However, in my debugging I often ssh into the Windows box via Cygwin, and run the app in that ssh session on a separate monitor from the monitor where the Windows application is being run. Under cygwin, I *do* have a stdin/stdout/stderr, and I can get debugging messages to show up there. The original problem I was trying to solve was how to easilly prevent these messages from showing up when the app is run from the Windows box directly (and not via cygwin). A non-stdout/stderr debugging facility is something I may set up (and I have the beginnings of that for handling exceptions -- something I'll have to deal with on users' behalf). For now the stdout/stderr debugging is a simple way to get the information on a separate monitor.
Plus, it's good to know how this works with the Gambit runtime library (and thus how to avoid unwanted consoles popping up).
Not completely obvious abstraction this console vs. windows application thing. How is it in Unix, GUI apps have their own stdin/out completely decoupled from the GUI workings, and generally it's piped to the app's console which may be the host terminal window of the X server, or /dev/null, sth like this.
This is one of my gripes about Windows. There's no reason that I'm aware of that they couldn't have set up a stdin/stdout/stderr facility for their GUI applications (without having to have the separate console), they just didn't. I suppose it might have something to do with DOS application compatibility from Windows 3.0, or something. I think mostly they just didn't care (though I'm open to being proved wrong about that).
REPLeffect
On Thu, Apr 12, 2012 at 5:34 PM, REPLeffect repleffect@gmail.com wrote:
On Thu, Apr 12, 2012 at 4:05 PM, Mikael mikael.rcv@gmail.com wrote:
Den 12 april 2012 23:44 skrev Marc Feeley feeley@iro.umontreal.ca:
My question is this: is it important that your application be a "windows" application? What are the benefits over a "console" application.
"console" applications are good for apps where you have a practical use of the app being hardwired to the presence of a console window only. So it's a nice default setting for developers, to have a console to print out to, take text input, and so on.
The issue is just that "console" applications, if launched not from a console (but from, say, Explorer), get a console window allocated to them at startup, even if there is no console IO.
If you want to make an UI app (for example, an alarm clock), obviously you want your users' experience to be about your UI only, and a console window popping up in the background would be quiet shocking for them.
^^ This is indeed the reason why my app has to be a windows app. The users would complain if a console window appears when the app is run (they would probably interpret that to mean something was wrong :-D ).
In console apps, you can deallocate the console I think, but even then it flashes by quickly on the screen, giving the user a feeling that something is not right.
Yes, one solution would be to use GetConsoleWindow() and hide the window immediately after calling AllocConsole() and then hide the window. But, again the users wouldn't like the flashing window any better.
"hide the window immediately after calling AllocConsole() and then hide the window."
^^ Ugh. Brought to you by the "Department of Redundancy Department".
You think you've read over a post enought times, then you reread it just after posting it and you find stuff like this!! :-D