3

I'm designing some cross platform tool, and I want to store some read only data, kind of resource data like:

  • Program icon
  • Images
  • Strings
  • "Manufacturated by ..." info
  • File version info

I'm trying to code the tool, either "pure c" or "c++".

I want to store the resource data using assembler, therefore, the data could be read in two ways:

(1) The program or shared library itselfs read its data, as a variable or assembler data section.

(2) The executable file or shared library file could be read by other program without been running or loaded.

The data will be only write once, when the code is compiled.

I found 2 possible ways to do this.

(1) Inline assembly. Add asm instructions, directly, to the "pure c" or "c++" files, several compilers, like Borland, MS, GNU, had some form of this.

(2) Generate the code and the assembly code in separate files, and, use a compiler tool, such a linker, build, or compiler, to compile togheter all.

I don't want to store assembler instructions, only data.

I'm targeting x86-32 bits processors, Windows, Linux & BSD, but, can be extended to other platforms or architectures, if possible.

I'm aware that Windows & Linux use different file formats such as PE or COFF or ELF binaries.

Any additional or alternative ideas ? Any suggestions, manuals, links on how to do this ?

Thanks.

umlcat
  • 4,091
  • 3
  • 19
  • 29
  • 1
    This answer may have the information you want: http://stackoverflow.com/a/4158997/12711 One method only works for the GCC toolchain, but the other method works with any C compiler. To allow a shared library to read the data, you'd need to have some methodd to get the pointer to the data to the shared library (easy to do via a function, if that's workable for you). – Michael Burr Feb 02 '12 at 01:32

2 Answers2

3

It's possibly a bit ugly, but here's one thing you could do which should be relatively portable: Store the entire contents of your data as a char array, starting and ending with a magic sequence. Possibly with a checksum.

e.g.

char data[]={
    't','h','e','_','s','t','a','r','t',0,
    // resource data here
    ....
    't','h','e','_','e','n','d',0,
    // maybe a checksum here
    ...
};

On all platforms I'm familiar with, those bytes will be stored contiguously in the file (which you can scan for the signatures to load up the resources). And of course, the data will be contiguous in memory while the program is running (and accessible as "data").

If something like this is not an option, you'll likely need to know more about your OS's executable file format.

Managu
  • 8,849
  • 2
  • 30
  • 36
3

One way to do it, is to append the data you want to store to the end of your compiled binary (maybe in a post-compile step), and directly after the data, store the size in a 32bit or 64bit integer.

Then to get the data out, in your code, open() your binary, seek to the end, read the size, then read backwards until you get all the data.

Simple and fairly portable.

fileoffset
  • 956
  • 6
  • 9