<!-- ##### SECTION Title ##### -->
Dynamic Loading of Modules

<!-- ##### SECTION Short_Description ##### -->
portable method for dynamically loading 'plug-ins'

<!-- ##### SECTION Long_Description ##### -->
<para>
These functions provide a portable way to dynamically load object files
(commonly known as 'plug-ins').
The current implementation supports all systems that provide
an implementation of dlopen() (e.g. Linux/Sun), as well as HP-UX via its
shl_load() mechanism, and Windows platforms via DLLs.
</para>

<para>
A program which wants to use these functions must be linked to the
libraries output by the command <command>pkg-config --libs gmodule-2.0</command>.
</para>

<para>
To use them you must first determine whether dynamic loading
is supported on the platform by calling g_module_supported().
If it is, you can open a module with g_module_open(),
find the module's symbols (e.g. function names) with g_module_symbol(),
and later close the module with g_module_close().
g_module_name() will return the file name of a currently opened module.
</para>
<para>
If any of the above functions fail, the error status can be found with
g_module_error().
</para>
<para>
The #GModule implementation features reference counting for opened modules,
and supports hook functions within a module which are called when the
module is loaded and unloaded (see #GModuleCheckInit and #GModuleUnload).
</para>
<para>
If your module introduces static data to common subsystems in the running
program, e.g. through calling <literal>g_quark_from_static_string ("my-module-stuff")</literal>,
it must ensure that it is never unloaded, by calling g_module_make_resident().
</para>

<para>
<example>
<title>Calling a function defined in a <structname>GModule</structname></title>
<programlisting>
/* the function signature for 'say_hello' */
typedef void (* SayHelloFunc) (const char *message);

gboolean
just_say_hello (const char *filename, GError **error)
{
  SayHelloFunc  say_hello;
  GModule      *module;

  module = g_module_open (filename, G_MODULE_BIND_LAZY);
  if (!module)
    {
      g_set_error (error, FOO_ERROR, FOO_ERROR_BLAH,
		   "&percnt;s", g_module_error (<!-- -->));
      return FALSE;
    }

  if (!g_module_symbol (module, "say_hello", (gpointer *)&amp;say_hello))
    {
      g_set_error (error, SAY_ERROR, SAY_ERROR_OPEN,
		   "&percnt;s: &percnt;s", filename, g_module_error (<!-- -->));
      if (!g_module_close (module))
	g_warning ("&percnt;s: &percnt;s", filename, g_module_error (<!-- -->));
      return FALSE;
    }

  if (say_hello == NULL)
    {
      g_set_error (error, SAY_ERROR, SAY_ERROR_OPEN, "symbol say_hello is NULL");
      if (!g_module_close (module))
	g_warning ("&percnt;s: &percnt;s", filename, g_module_error (<!-- -->));
      return FALSE;
    }

  /* call our function in the module */
  say_hello ("Hello world!");

  if (!g_module_close (module))
    g_warning ("&percnt;s: &percnt;s", filename, g_module_error (<!-- -->));

  return TRUE;
}
</programlisting>
</example>
</para>

<!-- ##### SECTION See_Also ##### -->
<para>

</para>

<!-- ##### SECTION Stability_Level ##### -->


