blob: 33d268312dba44d10a2bd2ddd924a74ce1245c85 [file] [log] [blame]
<!-- ##### 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 ##### -->