0

I would like to integrate a C library into my C++/Qt project. The library accepts a FILE* stream in order to print debug messages (rather than providing a hook for a logging callback function...).

It works properly if I just pass stderr, but I would like to integrate this into my own logging infrastructure, which uses qDebug() and co.

My initial idea was to use socketpair(), get the FILE* stream of the sending side's fd, pass it to the library, and handle the receiving side with QSocketNotifier, but I hit 2 issues with it:

  • It's not multiplatform, although there are implementations for Windows.
  • My application is single-threaded (and I want to keep it that way), and this means that the socketpair's 2 sockets are written and read from the same thread. This seems to be ending up with a deadlock after a while.

What are other methods existing to provide a FILE* stream, integrate its reading into Qt's event loop, doesn't require multiple threads, and is multiplatform?

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
zgyarmati
  • 1,135
  • 8
  • 15

1 Answers1

1

As long as you can get a file descriptor to your storage, you can get FILE* from it using unportable fdopen on Linux and _fdopen on Windows.

You can also create a regular pipe both on Linux and Windows, using pipe/_pipe.

And a pipe should integrate with Qt event loop. I am not familiar with Qt APIs, may be it exposes portable APIs for that. May be you can use QLocalSocket Class:

The QLocalSocket class provides a local socket. On Windows this is a named pipe and on Unix this is a local domain socket.

It has qintptr QLocalSocket::socketDescriptor() const method that returns the file descriptor that can be wrapped with fdopen to make a FILE*.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • [Calling Qt functions from Unix signal handlers](http://doc.qt.io/qt-5/unix-signals.html) give useful advice related to the "pipe to self" trick – Basile Starynkevitch Jul 16 '17 at 18:30
  • @BasileStarynkevitch That example could just use one pipe for all signals writing `signo` into it, rather than a `socketpair` for each passing no useful data. – Maxim Egorushkin Jul 16 '17 at 18:34
  • @MaximEgorushkin, i want to tweak the messages (prefix it with timestamp, tag like [DGB], etc), so directly giving access to the storage not an option. I'm going to try pipe(), thx. – zgyarmati Jul 16 '17 at 19:43
  • @BasileStarynkevitch, yes, i know this, but it uses socketpair() which i mentioned in my question. – zgyarmati Jul 16 '17 at 19:44