Applications and libraries often contain binary or textual data that is
really part of the application, rather than user data. For instance
Gtk::Builder
.glade
files,
splashscreen images, Gio::Menu
markup xml, CSS files,
icons, etc. These are often shipped as files in $datadir/appname
,
or manually included as literal strings in the code.
The Gio::Resource
API and the glib-compile-resources
program provide a convenient and efficient alternative to this, which has some nice properties. You
maintain the files as normal files, so it's easy to edit them, but during the build the files
are combined into a binary bundle that is linked into the executable. This means that loading
the resource files is efficient (as they are already in memory, shared with other instances) and
simple (no need to check for things like I/O errors or locate the files in the filesystem). It
also makes it easier to create relocatable applications.
Resource bundles are created by the glib-compile-resources program which takes an xml file that describes the bundle, and a set of files that the xml references. These are combined into a binary resource bundle.
An example:
<?xml version="1.0" encoding="UTF-8"?> <gresources> <gresource prefix="/toolbar"> <file preprocess="xml-stripblanks">toolbar.glade</file> <file>rain.png</file> </gresource> </gresources>
This will create a resource bundle with the files
/toolbar/toolbar.glade
/toolbar/rain.png
You can then use glib-compile-resources to compile the xml to a binary bundle
that you can load with Gio::Resource::create_from_file()
.
However, it's more common to use the --generate-source
argument to create a C source file to link directly into your application. E.g.
$ glib-compile-resources --target=resources.c --generate-source toolbar.gresource.xml
Once a Gio::Resource
has been created and registered all the data
in it can be accessed globally in the process by using API calls like
Gio::Resource::open_stream_from_global_resources()
to stream the data or Gio::Resource::lookup_data_in_global_resources()
to get a direct pointer to the data. You can also use URIs like resource:///toolbar/rain.png
with Gio::File
to access the resource data.
Often you don't need a Gio::Resource
instance,
because resource data can be loaded with methods such as
Gdk::Pixbuf::create_from_resource()
,
Gtk::Builder::add_from_resource()
and
Gtk::Image::set_from_resource()
.