How to embed resources into a single executable?

2019-04-26 06:34发布

问题:

If you've ever used the tool Game Maker, it's a bit like that. I want to be able to take all my sounds, images, and everything else of the like and embed them into a single C++ executable. Game Maker would have a built-in editor, and would have the images embedded into the .gmk file, and when you'd open it it would read the images, and display them in the game. I'm thinking he had the images saved not as images, but as pure data stored in the .gmk file and interpreted by the editor or by some interpreter written into the .exe. How would I go about making something similar?

回答1:

The windows resource system works like this, so if you make a WinAPI or MFC application, you can use this. Also, Qt provides the same functionality, but in a platform independent way. They just write the files in raw binary format into a byte array in a normal C++ file, so they get compiled as data into the exe. Then they provide functions for accessing these data blocks like normal files, although I don't know how they really work. Probably a special implementation of their file class which just accesses those byte array variables.



回答2:

For images only, a very simple approach is to use the XPM format.

This format is a valid C/C++ header, so you can include it directly into a C++ source file and use it directly.

The main issue with this approach is that XPM is not a compressed format, so uses a lot of storage. In consequence, in practice I only seen this used for icons and small graphical objects, but in principle you could do more.

The other cool thing about XPM is that it's human readable - again great for designing small and simple icons.

To generalize this idea to other formats, what you could do is to create a compile chain that:

  1. Encodes the target file as ASCII (Uuencode or such)
  2. Turns that into a single named C String in a source file.
  3. Create a header just declaring the name
  4. Define a function recovering the binary form from the string


回答3:

For the Windows OS I have a solution if you are willing to use another tool and possibly framework. Try the "peresembed" tool. It embeds files into PE image sections so you can have all your images, sounds and configuration files in just one EXE file. Supports compression too, although you do need a ZIP in-memory reading framework then. Can even embed files into the PE resource tree based on their relative file paths.

Example usage:

peresembed -file content.txt _export_to_resolve input.exe output.exe

In your C++ file you have:

struct embedded_data
{
    void *dataloc;
    size_t datasize;
};

extern "C" __declspec(dllexport) const volatile embedded_data _export_to_resolve = { 0 };
  • Get peresembed from: https://osdn.net/projects/pefrm-units/releases/70746
  • Showcase video: https://www.youtube.com/watch?v=1uYdjiZc5XI