0

We are developing C++ applications for Windows, Mac and Linux. The application have many binary resources, and for some reason we need to pack them within executable binary, instead of laying at directories (or Apple App bundle).

At current, we use a script to convert these resources into C++ array constants, then compile and link them. However this approach have so many deficiencies:

  • You have to compile the resource source code, it takes time and is unnecessary in essential.
  • The resource source codes would be parsed by IDE. As they are large, code analytic is greatly slowed down.
  • MSVC have limit on source code size, so large resources (several MB) must be separated into many parts then concatenated at run-time.

After some study, I found some solutions:

  • In Windows, I can use .rc files and related WinAPI.
  • In Linux, I can directly convert arbitrary binary file into obj file via objcopy.

However, there are still some questions remaining:

  • The use of WinAPI to fetch resources needs many functions to access one resource. Is there any simpler ways in Windows?
  • How to do it in Mac?
jiandingzhe
  • 1,881
  • 15
  • 35
  • 1
    There was once a similar question [SO: How to include data object files (images, etc.) in program and access the symbols?](https://stackoverflow.com/q/47414607/7478597) where I suggested a quite simple to implement alternative: [Embed binary contents in variables](https://stackoverflow.com/a/47415163/7478597). – Scheff's Cat Oct 26 '18 at 06:05
  • @Scheff This is same with what we currently using. – jiandingzhe Oct 26 '18 at 07:47
  • I should've read your question fully. ;-) Concerning the re-compile I'm not that afraid so much. If done right this concerns the binary data only. (Code might use it with `extern` variables - no recompile of that code necessary.) I missed the part with _(several MB)_ - yeah, that's a problem specifically with MSVC. (We usually haven't that big data to include.) – Scheff's Cat Oct 26 '18 at 07:56

1 Answers1

1

A quite common trick, most notably used for self-extracting archives or scripting language to executable compilers, is to append the resources at the end of the executable file.

Windows:

copy app.exe+all-resources app-with-resources.exe

Linux:

cp executable executable-with-resources
cat all-resources >>executable-with-resources

Then you can read your own executable using fopen(argv[0]) for example. In order to jump at the correct position, i.e. beginning of resources, a possible solution is to store the size of the executable without resources as the last word of the file.

FILE* fp = fopen(argv[0], "rb");
fseek(fp, -sizeof(int), SEEK_END);
int beginResourcesOffset;
fread(&beginResourcesOffset, 1, sizeof(int), fp);
fseek(fp, beginResourcesOffset, SEEK_SET);

Be careful with this solution though, anti-virus on windows sometimes don't like it. There probably are better solutions.

QuentinC
  • 12,311
  • 4
  • 24
  • 37