From: Jonathan A. <jo...@jo...> - 2009-12-29 19:55:18
|
Hi all, Im trying to write a console application that works on both linux and windows and its driving me insane... Im using conio.h, but kbhit just blocks ? Anyone any idea how I write a simple console application that actually workes on console window in XP ? The linux version of the same application builds and runs but has an extra step of entering and exiting raw mode on the tty. I need processing in the main loop so keyboard input can not block. Thanks, Jon |
From: Erwin W. <wat...@xs...> - 2009-12-29 21:37:17
|
Jonathan Andrews schreef: > Hi all, > > Im trying to write a console application that works on both linux and > windows and its driving me insane... > > Im using conio.h, but kbhit just blocks ? > > Anyone any idea how I write a simple console application that actually > workes on console window in XP ? The linux version of the same > application builds and runs but has an extra step of entering and > exiting raw mode on the tty. > > I need processing in the main loop so keyboard input can not block. > > Thanks, > Jon > My experience is that conio is not working well on Windows. Even if you use Borland C compiler. DJGPP has excellent conio support. If a DOS program is sufficient you could use DJGPP. Otherwise I would advise to use curses instead of conio, Ncurses on Linux and PDcurses on Windows. regards, -- Erwin Waterlander Eindhoven http://www.xs4all.nl/~waterlan/ |
From: Jonathan A. <jo...@jo...> - 2009-12-30 03:14:35
|
On Tue, 2009-12-29 at 22:36 +0100, Erwin Waterlander wrote: > Jonathan Andrews schreef: > > Hi all, > > > > Im trying to write a console application that works on both linux and > > windows and its driving me insane... > > > > Im using conio.h, but kbhit just blocks ? > > > > Anyone any idea how I write a simple console application that actually > > workes on console window in XP ? The linux version of the same > > application builds and runs but has an extra step of entering and > > exiting raw mode on the tty. > > > > I need processing in the main loop so keyboard input can not block. > > > > Thanks, > > Jon > > > My experience is that conio is not working well on Windows. Even if you > use Borland C compiler. I dont remember borlands kbhit being broken ! > DJGPP has excellent conio support. If a DOS program is sufficient you > could use DJGPP. > Otherwise I would advise to use curses instead of conio, Ncurses on > Linux and PDcurses on Windows. Thanks, useful info :-) I have written the application using ANSI sequences, I didn't fancy recoding it for curses. I followed your tip and download PDcurses, that had lots of PeekEvent windows code looking for key events. After much searching and hacking I found this: http://cboard.cprogramming.com/cplusplus-programming/13937-kbhit-portability.html MinGW conio kbhit is bust, cost me an entire day of pissing about - maybe mingw should mention this in the notes......... Thanks for the help :-) Jon |
From: Keith M. <kei...@us...> - 2009-12-30 11:21:09
|
On Wednesday 30 December 2009 03:13:16 Jonathan Andrews wrote: > MinGW conio kbhit is bust, For the record, it *isn't* MinGW's kbhit(); the implementation comes directly from Microsoft, via the system DLLs (MSVCRT). Here's what MSDN has to say [*] about it: http://msdn.microsoft.com/en-us/library/ms235390(VS.80).aspx |kbhit |This POSIX function [?] is deprecated beginning in Visual C++ 2005. |Use the ISO C++ conformant _kbhit instead. [?] Huh? What's this all about. AFAIK, kbhit() is not, and never has been a POSIX function; (it certainly doesn't get a mention in IEEE-1003.1.2004, the current POSIX specification, as searched by: http://www.opengroup.org/cgi-bin/kman2?value=kbhit ). [*] Okay, that's pertinent for the VS.2005 implementation, while the system MSVCRT, used by MinGW, is expected to be VS.6.0 compliant; in any case, deprecated doesn't mean discontinued, so we may reasonably expect kbhit() to exhibit the same behaviour as _kbhit(), and MinGW's libmoldname.a will make it so. > cost me an entire day of pissing about > - maybe mingw should mention this in the notes......... Why? This trivial test case works perfectly [**] for me, both with kbhit() and with _kbhit() (as shown here): $ cat tkbhit.c #include <conio.h> #include <stdio.h> #include <windows.h> int main() { int key = 0; const char *spinner = "/-\\|"; const char *flag = spinner; while( key != 27 ) { if( *flag == '\0' ) flag = spinner; printf( "%c\b", *flag++ ); Sleep( 500 ); if( _kbhit() ) printf( "\nkbhit: %d\n", key = _getch() ); } return 0; } $ gcc -o tkbhit.exe tkbhit.c $ ./tkbhit \ kbhit: 122 / kbhit: 27 $ [**] Running in a virtualised (VirtualBox) WinXP-SP2 on my Ubuntu-8.04-LTS box it exhibits the above (expected) behaviour. Under Wine, on the same host, the kbhit() events go undetected, but in neither case does kbhit() block, as you describe; (IOW, in both cases, the "spinner" is continuously refreshed by the repeated printf() call). -- Regards, Keith. |
From: Tor L. <tm...@ik...> - 2009-12-30 12:53:40
|
Isn't the whole concept of "console" apps that still are partly "GUI" and "fake event driven" (polling) in the sense that they use "raw" IO, use kbhit() etc, a relic from MS-DOS times anyway? But I digress. This trivial test program works fine for me, Works the same when built with MSVC6, MSVC9 or MinGW, and run in a console window: #include <conio.h> #include <stdio.h> int main (int argc, char **argv) { while (!_kbhit()) ; printf ("\nYou hit '%c'\n", _getch()); return 0; } Note that running this program loads one CPU ("core") close to 100%, the CPU time being spent (on Windows 7) by the program itself, the conhost.exe and csrss.exe processes. Is that really what you want? > MinGW conio kbhit is bust The kbhit() you call in MinGW -built code is in msvcrt.dll, it is not originating from MinGW in any way. My guess is that your problem is caused by using rxvt. That rxvt works oddly is not really a MinGW problem (but yeah, I understand that it might be hard to see what is MinGW and what is MSYS). Using rxvt is really not recommended, although I can't say where on the MinGW and MSYS site that is said... --tml |
From: Jonathan A. <jo...@jo...> - 2009-12-30 15:28:40
|
On Wed, 2009-12-30 at 14:52 +0200, Tor Lillqvist wrote: > Isn't the whole concept of "console" apps that still are partly "GUI" > and "fake event driven" (polling) in the sense that they use "raw" IO, > use kbhit() etc, a relic from MS-DOS times anyway? But I digress. > > This trivial test program works fine for me, Works the same when built > with MSVC6, MSVC9 or MinGW, and run in a console window: > > #include <conio.h> > #include <stdio.h> > > int main (int argc, char **argv) > { > while (!_kbhit()) > ; > > printf ("\nYou hit '%c'\n", _getch()); > return 0; > } > > Note that running this program loads one CPU ("core") close to 100%, > the CPU time being spent (on Windows 7) by the program itself, the > conhost.exe and csrss.exe processes. Is that really what you want? > > > MinGW conio kbhit is bust > > The kbhit() you call in MinGW -built code is in msvcrt.dll, it is not > originating from MinGW in any way. > > My guess is that your problem is caused by using rxvt. That rxvt works > oddly is not really a MinGW problem (but yeah, I understand that it > might be hard to see what is MinGW and what is MSYS). Using rxvt is > really not recommended, although I can't say where on the MinGW and > MSYS site that is said... > Thanks everyone for their comments. I foolishy did not preserve a snapshot at the point it was blocking. I was using mingw5.1.4.exe windows package to build the exe, but I dont have any more solid information. My application is test code for a display application, it generates UDP broadcast packets in response to keypresses. Im building both linux, linux-arm and windows versions from a linux devel machine, using mingw under wine to produce the windows binary. I use a shell script to build everything rather than make, example: echo -e "Compiling udptxtest.c \t\t\t -> udptxtest" cc udptxtest.c -o udptxtest -lm if [ "$HASCROSS" == "1" ]; then echo -e "Compiling udptxtest.c \t\t\t -> udptxtest-arm" arm-softfloat-linux-gnu-gcc udptxtest.c -static -l:"$JPLIB" -lm -o udptxtest-arm -O2 fi # If windows mingw package installed under wine then produce windows .exe if [ -f $HOME/.wine/drive_c/MinGW/bin/gcc.exe ]; then echo -e "Compiling udptxtest.c \t\t\t -> udptxtest.exe" gcc.exe udptxtest.c -o udptxtest.exe -lws2_32 -D MINGW #if [ -f ./udptxtest.exe ]; then #echo "Ok, built Windows executable" #fi fi The code main loop does this .... // ******************************************************************************************************************************** // Main loop, read keyboard and keep controls within limits while (quit!=TRUE) { // Before we start the loop take a copy of teldata //memcpy(&pteldata,&teldata,sizeof(struct telemetry_0x04_defs)); // Keep a copy for comparison later key=0; // Start with the assumption of no key #ifdef MINGW if (hitkb()==0) key=getch(); #else // Linux if (kbhit()!=0) // On linux test for next key ? key=getc(stdin); #endif if (key>13) { //printf("key=%d",key); fflush(stdout); if ((key=='q')|(key=='Q')) quit=TRUE; Under wine the windows console application never sees the keypress event, so just flops around the idle loop. When I started out coding it seemed to just block on kbhit in both wine and on a real windows 2000 machine. Now I need to I cant reproduce the behavior, but I have changed many many things including the version of MinGW. The test programs from yourself and Keith both work as expected on the real windows machine. Many thanks for your time, maybe its user error on my part or some weird interaction I cant reproduce :-( Cheers, Jon |
From: Keith M. <kei...@us...> - 2009-12-30 15:55:15
|
On Wednesday 30 December 2009 15:28:06 Jonathan Andrews wrote: > I was using mingw5.1.4.exe windows package to build the exe, but I > dont have any more solid information. And that much is completely nebulous; it tells us what version of the installer application you used, but that in itself tells us nothing about what you actually installed -- the installer payload may change any arbitrary number of times during the life cycle of any particular version of the installer. All we can deduce is that gcc would have come from the 3.x series, but the runtime support and binutils could have been any version. > Under wine the windows console application never sees the keypress > event, so just flops around the idle loop. Note that I observed the same phenomenon. That would indicate an issue with Wine, rather than with MinGW. > Many thanks for your time, maybe its user error on my part or some > weird interaction I cant reproduce :-( Don't you just hate that class of defect? -- Regards, Keith. |
From: Jonathan A. <jo...@jo...> - 2009-12-30 16:27:18
|
On Wed, 2009-12-30 at 15:54 +0000, Keith Marshall wrote: > On Wednesday 30 December 2009 15:28:06 Jonathan Andrews wrote: > > I was using mingw5.1.4.exe windows package to build the exe, but I > > dont have any more solid information. > > And that much is completely nebulous; it tells us what version of the > installer application you used, but that in itself tells us nothing > about what you actually installed -- the installer payload may change > any arbitrary number of times during the life cycle of any particular > version of the installer. All we can deduce is that gcc would have > come from the 3.x series, but the runtime support and binutils could > have been any version. Yes, im aware of this, hence the lack of solid information. To make life worse I also updated the service pack on the windows machine, almost certainly replacing the crt dlls. I just blundered blindly through it in the hope of a resolution, in hindsight I should have preserved the non working test case. At one point I had simple test with a kbhit that just stalled, but know i've changed everything - test code, compiler and windows itself...doh !....... > > Many thanks for your time, maybe its user error on my part or some > > weird interaction I cant reproduce :-( > > Don't you just hate that class of defect? Yep - fortunately doesn't happen often. After 2 weeks of solid coding its more than possible it was finger trouble on my part. Not helped by starting off using wine for testing the exe. I did figure out wine was broken and move onto a real windows box..... My other hated class of defect is the sloppy pointer that often points to RAM the process owns, but not always. Random infrequent segfault, but never when you start the debugger first. Cheers, Jon |