Re: [gtk-list] gmodule



On Mon, 14 Sep 1998, Marcus Brubaker wrote:

> Are there any places were documentation or example code is available for
> this?  Are there any programs currently using this?  Plus, if someone
> could give me a basic idea of what it is for and how it might be used I
> would appreciate it.  Thanks.

gmodule is basically a wrapper around dlopen() or similar implementations
for dynamic (runtime) loading of object files.
the api is pretty straight forward, you first figure whether dynamic loading
is supported on your platform by evaluating the return value of
g_module_supported(), and then open a module with g_module_open(), use its
symbols (e.g. function names) after retriving them through g_module_symbol()
and later close that module again with g_module_close().
if one of the avbove functions failed, the error status can be retrived through
g_module_error() (this even works for g_module_supported()==FALSE).
g_module_name() will return the file name of a currently opened module.

on a technical note, the gmodule implementation features reference counting
for opened modules and provides a special auto-hook upon module loading
to check for success. i.e. if your module exports a function:
G_MODULE_EXPORT const gchar* g_module_check_init (GModule *module);
it will be executed upon g_module_open() time and can return an error string
if the loading failed (e.g. because of an internal version mismatch against
the running program).
the current gmodule implementation features all systems that provide
an implementation of dlopen(), and also features HP-UX via its shl_load()
mechanism, though i haven't yet gotten a chance to test that code portion.
in the future, i'd like to implement gmodule for as many systems as possible,
which is basically a matter of me getting access to them or someone else
being willing to provide a working implementation.

if your module introduces static data to common subsystems in the running
program, e.g. through calling g_quark_from_static_string ("my-module-stuff),
it needs to take care to not being able to be unloaded again. this can be
achived by making the module hold a reference to itself:
  /* make ourselves resident */
  g_module_open (g_module_name (module), G_MODULE_BIND_LAZY);
for the future, i think i'm going to provide a convenience function like
void g_module_make_resident (GModule *module);
for this.

since the gmodule stuff currently only exists in the CVS version of glib
(1.1.3 has yet to be released), i should mention that the current CVS
gtk also features dynamic modules already, which can be loaded by
passing an additional --gtk-module=mymodule to any gtk program (assumed
that libmymodule.so is somewhere in the dynamic loader's path).
gtk features an extra initialization call for its modules, which has the
signature:
G_MODULE_EXPORT void gtk_module_init (gint *argc, gchar ***argv);
the CVS module GLE already makes use of this facility, after you checked
out GLE, compiled and installed it, you can invoke e.g.
$ testgtk --gtk-module=gle
and then press ctrl+alt+tab in any of testgtk's windows to actually activate
gle.

finally, as an example, here are the g_module_check_init() and
gtk_module_init() functions provided by GLE:

/* --- GLE Module stuff --- */
G_MODULE_EXPORT const gchar* g_module_check_init (GModule *module);
const gchar*
g_module_check_init (GModule *module)
{
  GModule *main;
  gchar *version_check = NULL;


  main = g_module_open (NULL, 0);
  if (!main)
    return "no main handle";
  if (!g_module_symbol (main, "gtk_major_version", &version_check) && version_check)
    return "no gtk library?";

  version_check = gtk_check_version (GTK_MAJOR_VERSION,
                                     GTK_MINOR_VERSION,
                                     GTK_MICRO_VERSION - GTK_INTERFACE_AGE);
  if (version_check)
    return version_check;

  /* make ourselves resident */
  g_module_open (g_module_name (module), G_MODULE_BIND_LAZY);

  return NULL;
}

G_MODULE_EXPORT void gtk_module_init (gint *argc, gchar ***argv);
void
gtk_module_init (int            *argc,
                 char           ***argv)
{
  gle_init (argc, argv);
}

> 
> Marcus Brubaker
> spoon@elpaso.net
> 

---
ciaoTJ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]