Getting a FILE* from a std::fstream

Bek picture Bek · Sep 20, 2008 · Viewed 47.4k times · Source

Is there a (cross-platform) way to get a C FILE* handle from a C++ std::fstream ?

The reason I ask is because my C++ library accepts fstreams and in one particular function I'd like to use a C library that accepts a FILE*.

Answer

Martin York picture Martin York · Sep 20, 2008

The short answer is no.

The reason, is because the std::fstream is not required to use a FILE* as part of its implementation. So even if you manage to extract file descriptor from the std::fstream object and manually build a FILE object, then you will have other problems because you will now have two buffered objects writing to the same file descriptor.

The real question is why do you want to convert the std::fstream object into a FILE*?

Though I don't recommend it, you could try looking up funopen().
Unfortunately, this is not a POSIX API (it's a BSD extension) so its portability is in question. Which is also probably why I can't find anybody that has wrapped a std::stream with an object like this.

FILE *funopen(
              const void *cookie,
              int    (*readfn )(void *, char *, int),
              int    (*writefn)(void *, const char *, int),
              fpos_t (*seekfn) (void *, fpos_t, int),
              int    (*closefn)(void *)
             );

This allows you to build a FILE object and specify some functions that will be used to do the actual work. If you write appropriate functions you can get them to read from the std::fstream object that actually has the file open.