RE: Hello and win32 g_io_channel help needed



Thank you for the reply Rob,

I ended up re-structuring to do polling every 250ms with a timeout on my
reads of zero.  It actually works quite well and fit's in to the scope
of the project which is not real-time anyway (it is for debugging a
simple IO board).

Such a shame since the callbacks would have been so nice, but as they
say "Dumb it down for the lowest common denominator"  Interesting how
windows is always the lowest common denominator.

Regards,

Burkey


-----Original Message-----
From: gtk-list-bounces gnome org [mailto:gtk-list-bounces gnome org] On
Behalf Of Robert Pearce
Sent: Friday, 4 May 2007 18:05
To: gtk-list gnome org
Subject: Re: Hello and win32 g_io_channel help needed

On Fri, 4 May 2007 10:40:30 +1000
"Burke.Daniel" <Daniel Burke IGT com> wrote:
> 
> I can easily achieve this under Linux with a little 
> re-organisation to separate out the platform specific 
> portions.
> 
> Does anyone have a fairly straightforward approach to
> do the same under windows?  If I cannot add a watch to
> the serial port I am afraid I may have to either fake
> it with a poll?

Short answer - no.

Longer answer - the Windows serial port handling is ugly and painful,
and really seriously not designed for this. It assumes you'll be using
a separate thread for everything. But there is just about provision for
it. Polling is even worse, because Windows doesn't support anything
equivalent to the Unix "select" call.

Here are some extracts from the code I've used on Windows (using
Borland C++ Builder) with some sucess:

  CommsLink::CommsLink ( const char * port, int baud ) {
     DCB ioDCB;

     hFile = CreateFile ( port, GENERIC_READ | GENERIC_WRITE, 0,
                          NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,
                          NULL );

     sReadOverlap.hEvent = 0;
     sReadOverlap.Offset = 0;
     sReadOverlap.OffsetHigh = 0;
     sWriteOverlap.hEvent = 0;
     sWriteOverlap.Offset = 0;
     sWriteOverlap.OffsetHigh = 0;

     if ( GetCommState ( hFile, &ioDCB ) )
     {
        // Set up appropriate attributes
        ioDCB.BaudRate = baud;
        ioDCB.ByteSize = 8;
        ioDCB.Parity = NOPARITY;
        ioDCB.StopBits = ONESTOPBIT;
        ioDCB.fParity = false;
        ioDCB.fBinary = true;
        SetCommState ( hFile, &ioDCB );
     }
     else
     {
        CloseHandle ( hFile );
        hFile = INVALID_HANDLE_VALUE;
        return;
     }
  }


  VOID CALLBACK HandleAsyncRx ( DWORD error, DWORD NumBytes,
                                LPOVERLAPPED lpOverlapped ) {
     CommsLink * cml = (CommsLink*)lpOverlapped->hEvent;
     lpOverlapped->hEvent = 0;
     cml->HandleRXEvent ( error, NumBytes );
  }


  bool CommsLink::SetRXHandler ( CommsCallback * cb )
  {
     RxCallBack = cb;
     sReadOverlap.hEvent = (void*)this;
     ReadFileEx ( hFile, AsyncReadBuffer, 8, &sReadOverlap,
                  HandleAsyncRx );
     return true;        // Should check something
  }


The problem is, Windows doesn't have the nice clean Gtk "main loop" to
poll for that event. So while the above has avoided needing a separate
thread, it doesn't work unless you have a timer tick regularly putting
your code into a suitable "interruptible sleep state" :

  void __fastcall TAppWindow::Timer1Timer(TObject *Sender)
  {
     if ( SleepEx ( 0, 1 ) != 0 )
     {
        // There was an event, which means we received some data
etc..


I had this more-or-less working when my customer decided to use Linux.
The port to Gtk was much easier.

Cheers,
Rob
_______________________________________________
gtk-list mailing list
gtk-list gnome org
http://mail.gnome.org/mailman/listinfo/gtk-list



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]