2

I'm using a third-party library that allows conversion between two file formats A and B. I would like to use this library to load a file of format A and convert it to format B, but I only need the converted representation in memory. So I would like to do the conversion without actually saving a file of the target format to disk and rather obtain an unsigned char* buffer or something similar. Unfortunately the libraries only conversion function is of the form

void saveAsB(A& a, std::FILE *const file);

What can I do? Is there any way to redirect the write operations performed on the handle to some buffer?

  • 1
    You may look at: http://stackoverflow.com/questions/1558772/how-to-get-file-descriptor-of-buffer-in-memory –  Oct 11 '13 at 11:05
  • 1
    If the library dynamically loads `fwrite()` from a DLL (MSVCRT, for example), you can try DLL injection to hook on `fwrite()`: http://en.wikipedia.org/wiki/DLL_Injection, although http://blogs.msdn.com/b/oldnewthing/archive/2007/12/13/6648400.aspx. The sanest, however, is to write to a temporary file and then read it back into memory. – alecov Oct 11 '13 at 11:40

2 Answers2

6

If your platform supports it, use open_memstream(3). This will be available on Linux and BSD systems, and it's probably better than fmemopen() for your use case because open_memstream() allocates the output buffer dynamically rather than you having to know the maximum size in advance.

If your platform doesn't have those functions, you can always use a "RAM disk" approach, which again on Linux would be writing a "file" to /dev/shm/ which will never actually reach any disk, but rather be stored in memory.

Edit: OK, so you say you're using Windows. Here's an outline of what you can try:

I found this reference useful in putting the pieces together: http://www.codeproject.com/Articles/1044/A-Handy-Guide-To-Handling-Handles

Edit 2: It looks like CreateFileMapping() and _open_osfhandle() may be incompatible with each other--you would be at least the third person to try it:

So, you can try what the last link suggested, which is to use setvbuf() to "trick" the data into flowing to a buffer you control, but even that has potential problems, e.g. it won't work if the library seeks within the FILE*.

So, perhaps you can just write to a file on some temporary/scratch filesystem and be done with it? Or use a platform other than Windows? Or use some "RAM disk" software.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
2

If you can rely on POSIX being available, then use fmemopen().