TL;DR: Why find and load data files at runtime, when you could be building them directly into the final executable and have the the OS automatically mmap them?
Lets say I'm writing a small application, and this application needs a couple of
read-only static data or resource files. I could write some code to install the
resource files into an appropriate location, find them when the program starts,
and then read the files in at runtime. However, if I'm writing it in a language
that uses ld
to create the final executable binary, I can just build the
static files directly into the resulting executable and just use them as
read-only memory buffers.
There are a couple of different ways to do this - I'm going to use the assembler approach, as it's efficient and lets me easily define my own symbol names.
Assuming I have a resource.dat
file that I want to include and use in my
program, I can write a small static.s
assembly file which will compile to an
object file containing the resource file and symbols pointing to it:
.section .rodata
.global dat_resource
.type dat_resource, @object
.align 4
dat_resource:
.incbin "resource.dat"
dat_resource_end:
.global dat_resource_size
.type dat_resource_size, @object
.align 4
dat_resource_size:
.int dat_resource_end - dat_resource
Once compiled (with gcc -c static.s
for example), it will simply be a .o
file
that can be linked into the final executable.
To use this data, you can simply reference the symbols from the object file. In
C++, it looks like this (note the extern "C"
- the symbols in static.s have C
linkage and don't go through the C++ name mangling process):
extern "C" {
extern char const dat_resource[];
extern unsigned const dat_resource_size;
}
With those declarations in scope, you can use dat_resource
as a pre-populated
memory buffer containing the data from resource.dat
- and you didn't have to
do any runtime work or write any file handling code to do it.