1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
Title: Dynamic Loading of Modules
## Dynamic Loading of Modules
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 Windows platforms via DLLs.
A program which wants to use these functions must be linked to the libraries
output by the command:
pkg-config --libs gmodule-2.0
To use them you must first determine whether dynamic loading is supported on
the platform by calling [`func@GModule.Module.supported`]. If it is, you can
open a module with [`func@GModule.Module.open`], find the module's symbols
(e.g. function names) with [`method@GModule.Module.symbol`], and later close
the module with [`method@GModule.Module.close`].
[`method@GModule.Module.name`] will return the file name of a currently
opened module.
If any of the above functions fail, the error status can be found with
[`func@GModule.Module.error`].
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 [callback@GModule.ModuleCheckInit] and
[callback@GModule.ModuleUnload]).
If your module introduces static data to common subsystems in the running
program, e.g. through calling API like:
```c
static GQuark my_module_quark =
g_quark_from_static_string ("my-module-stuff");
```
it must ensure that it is never unloaded, by calling
[`method@GModule.Module.make_resident`].
### Calling a function defined in a GModule
```c
// 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 == NULL)
{
g_set_error (error, FOO_ERROR, FOO_ERROR_BLAH,
"%s", g_module_error ());
return FALSE;
}
if (!g_module_symbol (module, "say_hello", (gpointer *)&say_hello))
{
g_set_error (error, SAY_ERROR, SAY_ERROR_OPEN,
"%s: %s", filename, g_module_error ());
if (!g_module_close (module))
g_warning ("%s: %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 ("%s: %s", filename, g_module_error ());
return FALSE;
}
// call our function in the module
say_hello ("Hello world!");
if (!g_module_close (module))
g_warning ("%s: %s", filename, g_module_error ());
return TRUE;
}
```
|