One of the coolest feature of POSIX systems is dynamic loading of libraries
and plugins. Everything is managed by dlopen() and its companions.
Loading at runtime means just:
- locating the library file
- use dlopen() to get a pointer to the library
- use dlsym() to get a pointer for each function inside the library you need
- use dlclose() to keep you code clean and help make the world a better place to live in ;-)
MacOS X and GNU/Linux both provide the same interface and code is straight portable. So, why I'm writing about that? Because you may have inserted in your code some check to locate the plugins of your application, dropping other files present in the same directory.
For example, Tagsistant uses /usr/local/lib/
as default path to store its plugins, which are named
libtagsistant_<mimetype>.so under GNU/Linux. And here enters
the matter: under MacOS X the extension is ".dylib" instead of
".so"!
The code which locates the plugins is the following:
#define TAGSISTANT_PLUGIN_PREFIX "libtagsistant_"
char *needle = strstr(de->d_name, TAGSISTANT_PLUGIN_PREFIX); if ((needle == NULL) || (needle != de->d_name))
continue;
needle = strstr(de->d_name, ".so");
if ((needle == NULL) || (needle != de->d_name + strlen(de->d_name) - 3))
continue;
This fragment is inserted into a cycle which traverse the whole plugins
list, that's why uses continue in reaction to failure. Number 3 in
last if statement is the length of ".so" string. This code compiles cleanly
under MacOS X but fails. After discovering the extension difference, I've
changed this code as:
#define TAGSISTANT_PLUGIN_PREFIX "libtagsistant_" char *needle = strstr(de->d_name, TAGSISTANT_PLUGIN_PREFIX); if ((needle == NULL) || (needle != de->d_name)) continue; #ifdef MACOSX # define PLUGIN_EXT ".dylib" #else
# define PLUGIN_EXT ".so"
#endif needle = strstr(de->d_name, PLUGIN_EXT); if ((needle == NULL) || (needle != de->d_name + strlen(de->d_name) - strlen(PLUGIN_EXT))) /> continue;
And now, finally, Tagsistant locates and loads its plugins!
Leave a comment