Re: Glib::Module
- From: Paul Davis <pjdavis engineering uiowa edu>
- To: Bart Verstraete <bartverstraete telenet be>
- Cc: gtkmm-list gnome org
- Subject: Re: Glib::Module
- Date: Fri, 23 Sep 2005 16:40:35 -0500
Bart,
From what I know about plugins, all symbols that you lookup should be C
names. Using C++ classes as names and such is a no no. The work around
is to define a method that just calls new Plugin()
I kind of hacked your code to get things situated correctly. Now
obviously this isn't nearly as fleshed out as it should be. I'm in the
middle of writing my own plugin loader and I'll post a link to it when I
get finished with that.
Glib::Module appears to be a very thinly veiled wrapper around libdl. I
haven't groked the source or anything, but the api is rather similar.
The passing a void*& pointer reference through me for a few minutes but
it all works.
Note that the tricky part is how you use the loaded symbol. You've got
to cast from void* to a function pointer. The syntax is a bit weird,
but here its the line:
Plugin* ( * LoadPlugin ) () ;
This declares LoadPlugin as a pointer to a function with signature:
Plugin* FUNCTION_NAME() ;
And then its just a matter of passing it to get_symbol by casting it to
void*&
Things to mention:
The loader should automatically guess the extension of the file your
loading. This makes things "portable". Ewww.
Notice the call Glib::Module::build_path( string directory, string name
). This even adds the lib prefix.
Glancing at the Glib::Module docs, it looks like it searches standard
search paths, ie /lib, /usr/lib. I know with libdl you can add to these
search paths to try and make your plugin findable. I never really got
it to work and its probably a better idea to use fully qualified paths
for security's sake.
Thats all I really have to say about that.
yay.
There *could* be a downfall to the way I'm doing this, but I think it
should work. If you try and load more than one plugin I don't know if
the defined LoadPlugin name will conflict. It would be easy enough to
write a second example plugin and load it as well. that should tell you
if its working.
Hope this helps anyone that cares.
Here's the code. I've included the scons build files just to point out
how trivial it makes things like this. Imagine trying to paste the
volumes of atuomake/autoconf stuff here. Get scons at www.scons.org.
The only dependancy is python > 1.5.(2 or 3) which was in version 7.2 or
so of Red Hat which was a long time ago. Enough preaching.
So here it is.
The directory layout:
./SConstruct
./main.cpp
./base_plugin.hh
./plugins/
./plugins/SConscript
./plugins/sampleplugin.cpp
/*
*
* ./Sconscript
*
*/
# vim: ft=python
env = Environment()
env.ParseConfig( 'pkg-config gtkmm-2.4 --cflags --libs' )
Export( 'env' )
env.Program( 'PluginTest', 'main.cpp' )
SConscript( 'plugins/SConscript' )
/*
*
* ./main.cpp
*
*/
#include <string>
using std::string ;
#include <iostream>
#include <glibmm/module.h>
#include "base_plugin.hh"
int main( int argc, char* argv[] )
{
if( argc != 2 )
{
fprintf( stderr, "usage: %s <plugin_name>\n" ) ;
return -1 ;
}
Plugin* ( * LoadPlugin ) () ;
Glib::Module plugin( argv[1] );
if( !plugin )
{
fprintf( stderr, "Failed to load plugin: %s :: %s\n", argv[1],
plugin.get_last_error().c_str() ) ;
}
else
{
fprintf( stderr, "Loaded plugin: %s\n",
plugin.get_name().c_str() ) ;
if( plugin.get_symbol( string( "LoadPlugin" ) , ( void*& )
LoadPlugin ) )
{
Plugin* loaded_plugin = LoadPlugin() ;
fprintf( stderr, "What does the plugin return? : %d\n",
loaded_plugin->action() ) ;
}
else
{
fprintf( stderr, "Failed to find plugin creation symbol.\n" ) ;
}
}
return 0;
}
/*
*
* ./base_plugin.hh
*
*/
#ifndef TESTPLUGINAPP_GENERIC_H
#define TESTPLUGINAPP_GENERIC_H
#define BEGIN_C_DECLS extern "C" {
#define END_C_DECLS }
class Plugin
{
public:
virtual int action() = 0;
};
BEGIN_C_DECLS
Plugin*
LoadPlugin() ;
END_C_DECLS
#endif //TESTPLUGINAPP_GENERIC_H
/*
*
* ./plugins/SConscript
*
*/
# vim: ft=python
Import( 'env' )
env.SharedLibrary( 'sampleplugin.cpp' )
/*
*
* ./plugins/sampleplugin.cpp
*
*/
#include "../base_plugin.hh"
#include <iostream>
class SamplePlugin : public Plugin
{
public:
int action()
{
fprintf( stderr, "Returning 9 from sample plugin.\n" ) ;
return 9 ;
}
} ;
Plugin*
LoadPlugin()
{
return new SamplePlugin() ;
}
Bart Verstraete wrote:
Hi here follows the samplecode and the question is. I get no errors,
it seems to load the moduleeee only when I try to acces the function
via get_symbol() the sample app print this:
Name of the plugin: plugins/sample.dll
Error: `action': The specified procedure could not be found.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]