Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 5

Qt-interest Archive, August 2007
printing message

Pages: Prev | 1 | 2 | Next

Message 1 in thread

Hi,
I am running a program that is calling a library which prints out 
messages with printf. I would like to be able to show these messages in 
a qt dialog . Is it possible to do so?
Thanks,
Marie

--
 [ signature omitted ] 

Message 2 in thread

Use QMessageBox.

Karl

On Wednesday 29 August 2007 11:07, Marie-Christine Vallet wrote:
> Hi,
> I am running a program that is calling a library which prints out
> messages with printf. I would like to be able to show these messages in
> a qt dialog . Is it possible to do so?
> Thanks,
> Marie
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body. List archive and information:
> http://lists.trolltech.com/qt-interest/

-- 
 [ signature omitted ] 

Message 3 in thread

Karl Ruetz wrote:
> Use QMessageBox.
>   
So far so good, but how can I get the printf to show in it?

--
 [ signature omitted ] 

Message 4 in thread

El Miércoles 29 Agosto 2007, Marie-Christine Vallet escribió:
> Karl Ruetz wrote:
> > Use QMessageBox.
>
> So far so good, but how can I get the printf to show in it?

To don't use printf. You use the string that you will use as a parameter in 
printf as the parameter of QMessageBox.

regards, Lisandro.



-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 5 in thread

Lisandro Damián Nicanor Pérez Meyer wrote:
> El Miércoles 29 Agosto 2007, Marie-Christine Vallet escribió:
>   
>> Karl Ruetz wrote:
>>     
>>> Use QMessageBox.
>>>       
>> So far so good, but how can I get the printf to show in it?
>>     
>
> To don't use printf. You use the string that you will use as a parameter in 
> printf as the parameter of QMessageBox.
>
> regards, Lisandro.
>
>
>
>   
the thing is it's in a library that does not use qt, so I guess it's not 
possible then.
Thanks,
Marie

--
 [ signature omitted ] 

Message 6 in thread

On August 29, 2007 11:01:33 am Marie-Christine Vallet wrote:
> Lisandro Damián Nicanor Pérez Meyer wrote:
> > El Miércoles 29 Agosto 2007, Marie-Christine Vallet escribió:
> >> Karl Ruetz wrote:
> >>> Use QMessageBox.
> >>
> >> So far so good, but how can I get the printf to show in it?
> >
> > To don't use printf. You use the string that you will use as a parameter
> > in printf as the parameter of QMessageBox.
> >
> > regards, Lisandro.
>
> the thing is it's in a library that does not use qt, so I guess it's not
> possible then.
> Thanks,
> Marie

You may be able to use QProcess to do this.  If it is a library linked in to 
your application rather than an external tool, matters are going to be more 
difficult.

--
 [ signature omitted ] 

Message 7 in thread

>
> You may be able to use QProcess to do this.  If it is a library linked in to 
> your application rather than an external tool, matters are going to be more 
> difficult.
>   
it is a library linked to my application

--
 [ signature omitted ] 

Message 8 in thread

On August 29, 2007 11:14:33 am Marie-Christine Vallet wrote:
> > You may be able to use QProcess to do this.  If it is a library linked in
> > to your application rather than an external tool, matters are going to be
> > more difficult.
>
> it is a library linked to my application

You may possibly be able to redirect stdout to a file so that your library 
dumps its output there, then read this file back in back in your main app.  
It's far from ideal, though, even if it could actually work.

--
 [ signature omitted ] 

Message 9 in thread

Chris Thompson wrote:
> On August 29, 2007 11:14:33 am Marie-Christine Vallet wrote:
>   
>>> You may be able to use QProcess to do this.  If it is a library linked in
>>> to your application rather than an external tool, matters are going to be
>>> more difficult.
>>>       
>> it is a library linked to my application
>>     
>
> You may possibly be able to redirect stdout to a file so that your library 
> dumps its output there, then read this file back in back in your main app.  
> It's far from ideal, though, even if it could actually work.
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
>   
it is possible to redirect the output in a file. The reason I want to do 
this is to let the user know that the process is still running, but it 
is a long process for which I would like to printout the message, a bit 
like kdevelop where you see the output of the compiling message.
thanks,
Marie

--
 [ signature omitted ] 

Message 10 in thread

Hopefully this won't sound *too* much like Greek:

I'm pretty sure it's possible to do what you want (at least on Unix/Linux)

The key to how easily depends on what "file" it's printing to. If it 
*really* using printf
(and not fprintf) then it's writing to stdout which has a file 
descriptor (fd) of 1. You can
create a "pipe"(% man 2 pipe) which has a write end and a read end. You 
dup2 the write end
of the pipe to fd1: dup2(<pipe_write_fd>,1) then when the library writes 
to fd 1, it will show
up on the read end of the pipe. You read the read end of the pipe and 
output what you get to
some qt text widget somewhere.

The above is just a hint. Sorry I don't have some code handy.

I'm vaguely thinking that Windows can do something similar, but it's 
been a while since
I "went to the metal" with Windows so I just don't remember any details.

Marie-Christine Vallet wrote:
> Chris Thompson wrote:
>> On August 29, 2007 11:14:33 am Marie-Christine Vallet wrote:
>>  
>>>> You may be able to use QProcess to do this.  If it is a library 
>>>> linked in
>>>> to your application rather than an external tool, matters are going 
>>>> to be
>>>> more difficult.
>>>>       
>>> it is a library linked to my application
>>>     
>>
>> You may possibly be able to redirect stdout to a file so that your 
>> library dumps its output there, then read this file back in back in 
>> your main app.  It's far from ideal, though, even if it could 
>> actually work.
>>
>> -- 
>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx 
>> with "unsubscribe" in the subject or the body.
>> List archive and information: http://lists.trolltech.com/qt-interest/
>>
>>
>>   
> it is possible to redirect the output in a file. The reason I want to 
> do this is to let the user know that the process is still running, but 
> it is a long process for which I would like to printout the message, a 
> bit like kdevelop where you see the output of the compiling message.
> thanks,
> Marie
>
> -- 
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with 
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>

--
 [ signature omitted ] 

Message 11 in thread

Peter Hackett schrieb:
> ...
> The key to how easily depends on what "file" it's printing to. If it 
> *really* using printf
> (and not fprintf) then it's writing to stdout which has a file 
> descriptor (fd) of 1. You can
> create a "pipe"(% man 2 pipe) which has a write end and a read end. You 
> dup2 the write end

Oh boy oh boy oh boy... where have all the good C programmers gone? :)

All the workarounds (printing into a file, putting the library into an 
*.exe and calling it with QProcess and reading from stdout, using pipes, 
.... *sigh*) probably work in one way or another.

But why don't you simply reroute the output written to stdout (and yes, 
printf really prints to stdout) to a buffer of yours (which is big 
enough to store the largest expected message from the library) at the 
beginning of your program (or at least just before you start calling 
functions from this library?)

Basically you want to close stdout first so its file descriptor (which 
is 1) becomes unused. After that you dup(licate) the file descriptor 
which is open on a given buffer of yours and since dup() uses the next 
unused file descriptor (which would be 1 or stdout in this case) 
everyone who outputs data into  stdout (such as printf) now writes into 
your buffer.

It's a bit messy on Windows though - AFAIK we even had to use a thread 
to constantly read from the buffer (in case there was something to 
read), because the writer could be blocked otherwise under certain 
circumstances. This is even documented somewhere in the MSDN.

On Unix (Windows) you want to look up dup() and company. Opening a 
stream (with a file descriptor) on a buffer should also be no problem.

I have some code somewhere in our SVN repository, but since we removed 
this approach (see below) I cannot find it right now (I would have to 
dig in the older revisions).

But I agree very much with one of the previous posts that message 
handling should never be done in a library (with printf - yucks!). Error 
codes (or exceptions, if you prefer) should be returned and user strings 
should only be allocated in the very top GUI layer.

Cheers, Oliver

--
 [ signature omitted ] 

Message 12 in thread

Peter Hackett schrieb:
> Hopefully this won't sound *too* much like Greek:
> ...
> The above is just a hint. Sorry I don't have some code handy.

Hmm, and the above was not all that wrong - in fact we did it more or 
less like that (sorry, I thought with "pipe" you meant the '|' shell 
pipe or something - didn't remember that there was the pipe() function ;)

In the meantime I have checked why we needed a thread (consumer) to read 
from the pipe as soon as there is something to read. This was the case 
on both Unix and Windows. I am not sure why a thread is needed at all, 
but oviously because you could end up in a deadlock if you had only one 
thread: when you write more than the pipe could store, then a successive 
write() would block forever.

Anyway, here's the code, take it "as is" ("It's your fault when there is 
a fault" and all the other lawyerish disclaimers apply), for Unix:

// BEGIN StreamDirector_Unix.cpp

#include <unistd.h>
#include <stdio.h>

#include "StreamReaderThread.h"
#include "StreamDirector.h"

// some convenience defines, for readability
#define PIPE_READ_HANDLE  0
#define PIPE_WRITE_HANDLE 1

static int                oldStdout;
static int                pipeHandle[2];
static StreamReaderThread *streamReaderThread = 0;

static void cleanUp()
{
     // close pipe
     (void)::close (pipeHandle[PIPE_READ_HANDLE]);
     (void)::close (pipeHandle[PIPE_WRITE_HANDLE]);
     // reset stdout
     (void)::dup2 (oldStdout, STDOUT_FILENO);
     (void)::close (oldStdout);

     if (streamReaderThread != 0)
     {
         delete streamReaderThread;
         streamReaderThread = 0;
     }
}

bool StreamDirector::redirectStdout (char *buffer, const unsigned int 
bufferSize)
{
     int status;

     // save stdout
     oldStdout = ::dup (STDOUT_FILENO);

      // create a pipe for communication between license library and the 
application
     status = pipe (pipeHandle);
     if (status != 0)
     {
         cleanUp();
         return false;
     }

     // redirect stdout, stdout is now written into the pipe
     (void)close (STDOUT_FILENO);
     status = dup2 (pipeHandle[PIPE_WRITE_HANDLE], STDOUT_FILENO);
     if (status == -1)
     {
         cleanUp();
         return false;
     }

     // unbuffered stdout
     setvbuf (stdout, NULL, _IONBF, bufferSize);

     streamReaderThread = new StreamReaderThread 
(pipeHandle[PIPE_READ_HANDLE], buffer, bufferSize);
     if (streamReaderThread == 0)
     {
         cleanUp();
         return false;
     }

     // start the thread
     streamReaderThread->start();

     return true;
}

void StreamDirector::finishStdout()
{
     char eof = static_cast<char>(EOF);

     /* write termination char to thread */
     (void)write (fileno(stdout), &eof, 1);

     // wait until thread ends
     if (streamReaderThread != 0)
     {
         streamReaderThread->wait();
     }

     cleanUp();

}

// END StreamDirector_Unix.cpp



Here's the code for Windows:

// BEGIN StreamDirector_Win32.cpp

#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>

#include "StreamReaderThread.h"
#include "StreamDirector.h"

static HANDLE writePipeHandle, readPipeHandle;
static HANDLE oldStdoutHandle;                  // saves the old 
standard out
//static HANDLE readerThreadHandle;             // thread which 
constantly reads from stdout
                                                 // until no more data 
is available
static StreamReaderThread *streamReaderThread = 0;

static void cleanUp()
{
     // close pipe
     (void)::CloseHandle (readPipeHandle);
     (void)::CloseHandle (writePipeHandle);
     // reset stdout
     (void)::SetStdHandle (STD_OUTPUT_HANDLE, oldStdoutHandle);
     (void)::CloseHandle (oldStdoutHandle);

     if (streamReaderThread != 0)
     {
         delete streamReaderThread;
         streamReaderThread = 0;
     }
}

bool StreamDirector::redirectStdout (char *buffer, const unsigned int 
bufferSize)
{
     int  hConHandle = 0;
     int  status     = 0;
     long lStdHandle = 0;
     FILE *fp        = NULL;

     // save stdout
     oldStdoutHandle = ::GetStdHandle (STD_OUTPUT_HANDLE);

     status = ::CreatePipe (&readPipeHandle, &writePipeHandle, NULL, 
bufferSize);

     if (status == 0)
     {
         cleanUp();
         return false;
     }

     // redirect stdout, stdout is now written into the pipe
     status = ::SetStdHandle (STD_OUTPUT_HANDLE, writePipeHandle);
     if (status == 0)
     {
         cleanUp();
         return false;
     }

     // redirect unbuffered stdout to the buffer - this cast produces a 
warning
     // but is okay, example taken from MSDev library
     lStdHandle = reinterpret_cast<long>(GetStdHandle (STD_OUTPUT_HANDLE));
     hConHandle = ::_open_osfhandle (lStdHandle, _O_TEXT);

     fp      = ::_fdopen (hConHandle, "w");
     *stdout = *fp;

     // unbuffered stdout
     ::setvbuf (stdout, NULL, _IONBF, bufferSize);

     /*
       because the process plays the role of producer and consumer, the 
consumer part has to run into
       a thread: if the producer writes more bytes into the pipe than 
the size of its buffer, the
       corresponding write function (e.g printf(), fprintf(stdout, ..), 
write(fileno(stdout), ..) blocks
       and the process ends in a deadlock. for prevent this situation, 
the thread continuously reads
       from the pipe as long as data is present.
     */
     // this cast produces a warning
     // but is okay, example taken from MSDev library
     hConHandle = ::_open_osfhandle 
(reinterpret_cast<long>(readPipeHandle), _O_TEXT);
     streamReaderThread = new StreamReaderThread (hConHandle, buffer, 
bufferSize);
     if (streamReaderThread == 0)
     {
         cleanUp();
         return false;
     }

     // start the thread
     streamReaderThread->start();

     return true;
}

void StreamDirector::finishStdout()
{
     char eof = static_cast<char>(EOF);

     /* write termination char to thread */
     ::write (fileno (stdout), &eof, 1);

     // wait until thread ends
     streamReaderThread->wait();

     cleanUp();

}

The threaded (QThread) consumer looks like this on Unix:

void StreamReaderThread::run()
{
     size_t nofRead = 0;
     size_t totRead = 0;
     char   *ptr    = m_buffer;  // points to the next entry to be written

     while (::ioctl (m_fd, FIONREAD, &nofRead) >= 0)
     {
         if (totRead + nofRead > m_bufferSize) // buffer overflow
             break;

         if (nofRead > 0)
         {
             ::read (m_fd, ptr, nofRead);

             totRead += nofRead;
             ptr += nofRead;

             if (((int)*(ptr-1) & 0x00FF) == (EOF & 0x00FF))  // EOF 
(too for IBM)
                 break;
          }
     }

     *(ptr-1) = 0;
}

And for Windows:


void StreamReaderThread::run()
{
     int nofRead   = 0;
     int bufferPos = 0;  // points to the next entry to be written

     while (true)
     {
         nofRead = read (m_fd, &m_buffer[bufferPos], m_bufferSize - 
nofRead);
         if (nofRead > 0)
         {
             bufferPos += nofRead;
         }
         if ((nofRead == 0) || (nofRead == -1) || (m_buffer[bufferPos - 
1] == static_cast<char>(EOF)))
         {
             if (bufferPos > 0)
             {
                 m_buffer[bufferPos - 1] = '\0';
             }
             else
             {
                 // read error, nothing read
                 m_buffer[0] = '\0';
             }
             // exit the thread
             break;
         }
     }

}

m_fd, m_buffer and m_bufferSize are given as parameters to the thread. 
The m_buffer must off course be large enough to hold all messages which 
are expected on stdout - in our case it is (or was, since we do not use 
this ugly code anymore) simply a fixed size array of char. You could 
also use a QByteArray or a QTextStream or whatever which would 
dynamically change its size.

Again, I'm not sure why the thread is really necessary - I got this code 
from another developer and he claimed to have taken this example from 
the MSDN or so. It worked, I did not ask questions ... ;)


Hope that gives you some inspirations ;)

Cheers, Oliver

--
 [ signature omitted ] 

Message 13 in thread

Till Oliver Knoll wrote:
> Peter Hackett schrieb:
>> Hopefully this won't sound *too* much like Greek:
>> ...
>> The above is just a hint. Sorry I don't have some code handy.
>
> Hmm, and the above was not all that wrong - in fact we did it more or 
> less like that (sorry, I thought with "pipe" you meant the '|' shell 
> pipe or something - didn't remember that there was the pipe() function ;)
>
> In the meantime I have checked why we needed a thread (consumer) to 
> read from the pipe as soon as there is something to read. This was the 
> case on both Unix and Windows. I am not sure why a thread is needed at 
> all, but oviously because you could end up in a deadlock if you had 
> only one thread: when you write more than the pipe could store, then a 
> successive write() would block forever.
>
> Anyway, here's the code, take it "as is" ("It's your fault when there 
> is a fault" and all the other lawyerish disclaimers apply), for Unix:
>
> // BEGIN StreamDirector_Unix.cpp
>
> #include <unistd.h>
> #include <stdio.h>
>
> #include "StreamReaderThread.h"
> #include "StreamDirector.h"
>
> // some convenience defines, for readability
> #define PIPE_READ_HANDLE  0
> #define PIPE_WRITE_HANDLE 1
>
> static int                oldStdout;
> static int                pipeHandle[2];
> static StreamReaderThread *streamReaderThread = 0;
>
> static void cleanUp()
> {
>     // close pipe
>     (void)::close (pipeHandle[PIPE_READ_HANDLE]);
>     (void)::close (pipeHandle[PIPE_WRITE_HANDLE]);
>     // reset stdout
>     (void)::dup2 (oldStdout, STDOUT_FILENO);
>     (void)::close (oldStdout);
>
>     if (streamReaderThread != 0)
>     {
>         delete streamReaderThread;
>         streamReaderThread = 0;
>     }
> }
>
> bool StreamDirector::redirectStdout (char *buffer, const unsigned int 
> bufferSize)
> {
>     int status;
>
>     // save stdout
>     oldStdout = ::dup (STDOUT_FILENO);
>
>      // create a pipe for communication between license library and 
> the application
>     status = pipe (pipeHandle);
>     if (status != 0)
>     {
>         cleanUp();
>         return false;
>     }
>
>     // redirect stdout, stdout is now written into the pipe
>     (void)close (STDOUT_FILENO);
>     status = dup2 (pipeHandle[PIPE_WRITE_HANDLE], STDOUT_FILENO);
>     if (status == -1)
>     {
>         cleanUp();
>         return false;
>     }
>
>     // unbuffered stdout
>     setvbuf (stdout, NULL, _IONBF, bufferSize);
>
>     streamReaderThread = new StreamReaderThread 
> (pipeHandle[PIPE_READ_HANDLE], buffer, bufferSize);
>     if (streamReaderThread == 0)
>     {
>         cleanUp();
>         return false;
>     }
>
>     // start the thread
>     streamReaderThread->start();
>
>     return true;
> }
>
> void StreamDirector::finishStdout()
> {
>     char eof = static_cast<char>(EOF);
>
>     /* write termination char to thread */
>     (void)write (fileno(stdout), &eof, 1);
>
>     // wait until thread ends
>     if (streamReaderThread != 0)
>     {
>         streamReaderThread->wait();
>     }
>
>     cleanUp();
>
> }
>
> // END StreamDirector_Unix.cpp
>
>
>
> Here's the code for Windows:
>
> // BEGIN StreamDirector_Win32.cpp
>
> #include <windows.h>
> #include <stdio.h>
> #include <fcntl.h>
> #include <io.h>
> #include <iostream>
> #include <fstream>
>
> #include "StreamReaderThread.h"
> #include "StreamDirector.h"
>
> static HANDLE writePipeHandle, readPipeHandle;
> static HANDLE oldStdoutHandle;                  // saves the old 
> standard out
> //static HANDLE readerThreadHandle;             // thread which 
> constantly reads from stdout
>                                                 // until no more data 
> is available
> static StreamReaderThread *streamReaderThread = 0;
>
> static void cleanUp()
> {
>     // close pipe
>     (void)::CloseHandle (readPipeHandle);
>     (void)::CloseHandle (writePipeHandle);
>     // reset stdout
>     (void)::SetStdHandle (STD_OUTPUT_HANDLE, oldStdoutHandle);
>     (void)::CloseHandle (oldStdoutHandle);
>
>     if (streamReaderThread != 0)
>     {
>         delete streamReaderThread;
>         streamReaderThread = 0;
>     }
> }
>
> bool StreamDirector::redirectStdout (char *buffer, const unsigned int 
> bufferSize)
> {
>     int  hConHandle = 0;
>     int  status     = 0;
>     long lStdHandle = 0;
>     FILE *fp        = NULL;
>
>     // save stdout
>     oldStdoutHandle = ::GetStdHandle (STD_OUTPUT_HANDLE);
>
>     status = ::CreatePipe (&readPipeHandle, &writePipeHandle, NULL, 
> bufferSize);
>
>     if (status == 0)
>     {
>         cleanUp();
>         return false;
>     }
>
>     // redirect stdout, stdout is now written into the pipe
>     status = ::SetStdHandle (STD_OUTPUT_HANDLE, writePipeHandle);
>     if (status == 0)
>     {
>         cleanUp();
>         return false;
>     }
>
>     // redirect unbuffered stdout to the buffer - this cast produces a 
> warning
>     // but is okay, example taken from MSDev library
>     lStdHandle = reinterpret_cast<long>(GetStdHandle 
> (STD_OUTPUT_HANDLE));
>     hConHandle = ::_open_osfhandle (lStdHandle, _O_TEXT);
>
>     fp      = ::_fdopen (hConHandle, "w");
>     *stdout = *fp;
>
>     // unbuffered stdout
>     ::setvbuf (stdout, NULL, _IONBF, bufferSize);
>
>     /*
>       because the process plays the role of producer and consumer, the 
> consumer part has to run into
>       a thread: if the producer writes more bytes into the pipe than 
> the size of its buffer, the
>       corresponding write function (e.g printf(), fprintf(stdout, ..), 
> write(fileno(stdout), ..) blocks
>       and the process ends in a deadlock. for prevent this situation, 
> the thread continuously reads
>       from the pipe as long as data is present.
>     */
>     // this cast produces a warning
>     // but is okay, example taken from MSDev library
>     hConHandle = ::_open_osfhandle 
> (reinterpret_cast<long>(readPipeHandle), _O_TEXT);
>     streamReaderThread = new StreamReaderThread (hConHandle, buffer, 
> bufferSize);
>     if (streamReaderThread == 0)
>     {
>         cleanUp();
>         return false;
>     }
>
>     // start the thread
>     streamReaderThread->start();
>
>     return true;
> }
>
> void StreamDirector::finishStdout()
> {
>     char eof = static_cast<char>(EOF);
>
>     /* write termination char to thread */
>     ::write (fileno (stdout), &eof, 1);
>
>     // wait until thread ends
>     streamReaderThread->wait();
>
>     cleanUp();
>
> }
>
> The threaded (QThread) consumer looks like this on Unix:
>
> void StreamReaderThread::run()
> {
>     size_t nofRead = 0;
>     size_t totRead = 0;
>     char   *ptr    = m_buffer;  // points to the next entry to be written
>
>     while (::ioctl (m_fd, FIONREAD, &nofRead) >= 0)
>     {
>         if (totRead + nofRead > m_bufferSize) // buffer overflow
>             break;
>
>         if (nofRead > 0)
>         {
>             ::read (m_fd, ptr, nofRead);
>
>             totRead += nofRead;
>             ptr += nofRead;
>
>             if (((int)*(ptr-1) & 0x00FF) == (EOF & 0x00FF))  // EOF 
> (too for IBM)
>                 break;
>          }
>     }
>
>     *(ptr-1) = 0;
> }
>
> And for Windows:
>
>
> void StreamReaderThread::run()
> {
>     int nofRead   = 0;
>     int bufferPos = 0;  // points to the next entry to be written
>
>     while (true)
>     {
>         nofRead = read (m_fd, &m_buffer[bufferPos], m_bufferSize - 
> nofRead);
>         if (nofRead > 0)
>         {
>             bufferPos += nofRead;
>         }
>         if ((nofRead == 0) || (nofRead == -1) || (m_buffer[bufferPos - 
> 1] == static_cast<char>(EOF)))
>         {
>             if (bufferPos > 0)
>             {
>                 m_buffer[bufferPos - 1] = '\0';
>             }
>             else
>             {
>                 // read error, nothing read
>                 m_buffer[0] = '\0';
>             }
>             // exit the thread
>             break;
>         }
>     }
>
> }
>
> m_fd, m_buffer and m_bufferSize are given as parameters to the thread. 
> The m_buffer must off course be large enough to hold all messages 
> which are expected on stdout - in our case it is (or was, since we do 
> not use this ugly code anymore) simply a fixed size array of char. You 
> could also use a QByteArray or a QTextStream or whatever which would 
> dynamically change its size.
>
> Again, I'm not sure why the thread is really necessary - I got this 
> code from another developer and he claimed to have taken this example 
> from the MSDN or so. It worked, I did not ask questions ... ;)
>
>
> Hope that gives you some inspirations ;)
>
> Cheers, Oliver
>
> -- 
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with 
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
Thanks,
It will probably take some time for me to understand the code and 
specially how to use it , but, I'm sure I will get inspired in the end....
Thank you very much,
Marie

--
 [ signature omitted ] 

Message 14 in thread

Marie-Christine Vallet schrieb:
> Till Oliver Knoll wrote:
>> ...
>> Anyway, here's the code, take it "as is" ("It's your fault when there 
>> is a fault" and all the other lawyerish disclaimers apply), for Unix:
>> [snip code]
> Thanks,
> It will probably take some time for me to understand the code and 
> specially how to use it , but, I'm sure I will get inspired in the end....

Well, the usage is pretty much straight forward: somewhere before you 
start calling your library functions (which call printf()) you simply put:

   char         myBuffer[1024]; // hopefully large enough ;)
   unsigned int bufferSize = 1024;
   if (StreamDirector::redirectStdout (myBuffer, bufferSize) == true)
   {
     // success
     ...
   }
   else {
     // error handling (pipe could not created, dup2 failed etc.)
     ...
   }

Note that the function redirectStdout() is declared static in the *.h 
(which I did not provide, but it's easily derived).

The code itself I admit is a mess... ;)

Cheers, Oliver

--
 [ signature omitted ] 

Message 15 in thread


Till Oliver Knoll wrote:
> Peter Hackett schrieb:
>> Hopefully this won't sound *too* much like Greek:
>> ...
>> The above is just a hint. Sorry I don't have some code handy.
...
>> In the meantime I have checked why we needed a thread (consumer) to 
>> read from the pipe as soon as there is something to read. This was 
>> the case on both Unix and Windows. I am not sure why a thread is 
>> needed at all, but oviously because you could end up in a deadlock if 
>> you had only one thread: when you write more than the pipe could 
>> store, then a successive write() would block forever.
...
Yes. The pipe has a finite size. If you didn't have a separate thread 
reading from the pipe,
the library could fill up the pipe and would block and "no one" would 
ever read from it.
Pipes have traditionally been used to set up communications between 
parent processes and
there children. (pipe(2) is used to implement "|" in the shells.)

--
 [ signature omitted ] 

Pages: Prev | 1 | 2 | Next