Question

My code currently uses a library that I pass a FILE* to and it reads a bunch of complicated configuration data using the fread() CRT API. I'd like to move the file to become an embedded resource within the file (a Windows DLL). Unfortunately, reading a Windows resource gives me the data directly as a void*....which I can't pass to the library.

What I'd like is to be able to get a FILE* that is backed by a memory buffer instead of a file on disk. Windows has CreateStreamOnHGlobal(), but that uses IStream* and I need a FILE*. Unfortunately, I can't find any solution that exists for Windows. Is this possible?

The solution I could use would be to write the resource data into a temporary file, pass the temp file to the configuration parser, and then delete the file....but that is extremely inefficient and I'm dealing with a large amount of data.

Was it helpful?

Solution

What you actually want is the equivalent of fmemopen() on Windows. No such equivalent exists.

You could use a named pipe as a workaround. You should be able to use fopen() to open the read end of a named pipe. The resource provider then passes the FILE * to the configuration parser while some other thread writes the resource data into the write end of the named pipe. This should be fine so long as the parser only wants to do sequential reads on the file (as opposed to seeking, which would not work on a pipe).

If you are willing to use Cygwin, it provides fmemopen().

OTHER TIPS

https://github.com/tamatebako/fmem is a wrapper for different platform/version specific implementations of in-memory files

It tries in sequence the following implementations:

  • open_memstream.

  • fopencookie, with growing dynamic buffer.

  • funopen, with growing dynamic buffer.

  • WinAPI temporary memory-backed file.

    When no other mean is available, fmem falls back to tmpfile()

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top