Archives for: May 2005, 18
05/18/05
Glib's GModules are fun :-) These functions provide a braindead interface to modular (think "plug-in based") programming. I wrote some testing code today (read the API a year ago or so but never played with it), here's a short introduction.
When writing module based applications there are mainly 2 parts: the modules, and the application using them. So we'll have to write these 2 things.
Getting started with the module is the easiest part:
#include <glib.h>
#include <gmodule.h>
G_MODULE_EXPORT void m_helloworld() {
g_print("Hello modular world!\n");
}
This code is pretty straight-forward. The only "strange" thing is G_MODULE_EXPORT, a platform-independent macro telling the compiler/linker to export the function.
Then comes the "client" application, a little more difficult. Comments inline:
#include <glib.h>
#include <gmodule.h>
/* A prototype of the function pointer we'll use */
/* void function(void) */
typedef void (*HelloWorldFunc) (void);
gint main(gint argc, gchar *argv[]) {
/* We need:
* - A handle to our module
* - A pointer to the function we'll import
* - Some helper strings */
GModule *module = NULL;
HelloWorldFunc hello = NULL;
gchar *module_path = NULL, *curr = NULL;
/* Check whether glib is compiled with module support */
if(g_module_supported() == FALSE) {
g_error("Modules not supported :(");
return 1;
}
/* We need to figure out the path to our module. In our test case, this
* is ".", so we want the current dir. */
curr = g_get_current_dir();
/* Create the path to the module. This function does quite a lot of
* of things, check the GModule API. */
module_path = g_module_build_path((const gchar *) curr, "module");
/* Don't we love debugging? */
g_debug("Module path: %s", module_path);
/* Finally we're able to open the module. We want lazy symbol resolving.
* This means we only want a symbol to be resolved if we request it.
* Once more, see the API for more information. */
module = g_module_open(module_path, G_MODULE_BIND_LAZY);
/* Get rid of those helper strings */
g_free(module_path);
g_free(curr);
/* Check whether the module was loaded successfully */
if(module == NULL) {
g_error("Unable to load module");
return 1;
}
/* Load the symbol and assign it to our function pointer.
* Check for errors */
if(g_module_symbol(module, "m_helloworld", (gpointer *) &hello) == FALSE) {
g_error("Unable to get function reference: %s", g_module_error());
return 1;
}
/* Now we can call our funtion.
* As you can see, we can call it as if it's a normal function.
* Don't we love function pointers? */
hello();
/* We're nice citizens and close all references when we leave */
if(g_module_close(module) == FALSE) {
g_error("Unable to close module: %s", g_module_error());
return 1;
}
return 0;
}
(this looks like a lot of code (well...) but if you strip all comments and debugging stuff/checks, you'll only have 10 lines or so)
Should be quite easy to understand too.
Now it's compile time. Of course, in a real-world situation, we'd use autotools to compile our libraries, we'd have a libtoolized library etc etc etc. Here we'll do it in the quick-and-dirty way:
# gcc -o libmodule.so -shared `pkg-config --libs --cflags glib-2.0 gmodule-2.0` module.c # gcc -o main `pkg-config --libs --cflags glib-2.0 gmodule-2.0` main.c # ls libmodule.so main main.c module.c # ./main ** (process:26533): DEBUG: Module path: /home/foo/bar/libmodule.so Hello modular world!
Loading all these symbols by hand is a boring task, so most of the time you'll create some API using vtables to make your life easier. More on this later (got to study now ;-) :|)
Yesterday, I placed gnome and all dependencies in my packages.keywords (with the ~x86 keyword of course) so I could install gnome 2.10. Worked fine, but when I booted a few hours later, my X-server couldn't start. Normally there should be no correlation between these two facts, but it's the only thing that changed between a working and a non-workig X. This is the error I recieve:
(EE) RADEON(0): Cannot map SYS BIOS
Ikke was here yesterday night, but he couldn't fix it too. He tried with vesa, some modules and xorg.conf from a working ubuntu liveCD, but all without any effect. We also recompiled xorg, but this also wasn't the solution.
If you know any, please let me know! If I find it, I'll sure post the solution here.
You can find a more detailed error log here and my xorg.conf file here. Yesterday I worked graphical till 18 hours (I don't know when I restarted my X then), but it didn't work after I booted up at 0.30 am this morning. The packages I emerged yesterday can be found in my genlop log.