Re: Dynamic libraries problem.
When I try to access the plugin (the dynamic library is CORRECTLY
loaded, and LD_LIBRARY_PATH is correctly set) it seems as if the
instance I am accessing from the main program were different from the
instance in which I register the plugin. Can anyone help? Maybe is a
link or order of initialization problem? Thanks for your time. This is
making me crazy.
I've been playing around with your plugin concept.
My setup:
test.cc -- testapplication includes singleton.h via plugin.h
plugin.cc -- defines plugin base class and PluginsManager
Singleton subclass. Builds the libplugin.so
library.
myplugin.cc Used to build myplugin.so to be loaded
by PluginsManager::init. Also includes singleton.h
via PluginsManager.
If you implement Singleton as described under
http://en.wikipedia.org/wiki/Singleton_pattern
it seems you really get two instances, one within the test
application and one within the myplugin.so. Singleton<PluginsManager>
CTor is called twice.
But if you do it like this:
<snip>
template<typename T> class Singleton {
public:
static T& instance() {
return Ptr== ? *(Ptr = alloc()) : *Ptr;
return *Ptr;
}
private:
static T * alloc() {
static T theSingleInstance;
return &theSingleInstance;
}
static T * Ptr;
};
</snip>
and define
template<>
PluginsManager *Singleton<PluginsManager>::Ptr = NULL;
in plugin.cc all is well. You still have a code duplication
but theSingleInstance is only allocated once because the Ptr
is shared between myplugin.so and the main application
within libplugin.so, and because static local objects with
a constructor within function alloc() are only allocated when
alloc is executed for the first time (once per binary)
as I had to learn from A. Alexandrescus "Modern C++ Design".
p134
HTH
O.
<snip>
<! -- plugin.h -->
#ifndef __PLUGIN_H
#define __PLUGIN_H
#include <iostream>
#include <map>
#include "singleton.h"
class Plugin {
public:
virtual void init() {
std::cerr << "Plugin:init" << std::endl;
}
};
typedef Plugin * PluginPtr;
typedef std::map<std::string,PluginPtr> PluginsMap;
class PluginsManager : public Singleton<PluginsManager> {
PluginsMap plugins_;
friend class Singleton<PluginsManager>;
public:
void init();
bool registerPlugin(const std::string & plugid, PluginPtr p);
PluginPtr getPlugin(const std::string & plugid);
private:
PluginsManager() {
};
};
#define REGISTER_PLUGIN(pluginid, plugintype, ns) const static bool
registered##ns = \
PluginsManager::instance().registerPlugin(pluginid,PluginPtr(new
plugintype))
#endif // __PLUGIN_H
<! -- singleton.h -->
#ifndef __SINGLETON_H
#define __SINGLETON_H
template<typename T> class Singleton {
public:
Singleton() {
std::cerr << "Singleton::CTor" << std::endl;
}
static T& instance() {
Ptr==NULL ? *(Ptr = alloc()) : *Ptr;
}
private:
static T * alloc() {
static T theSingleInstance; // assumes T has a protected default
constructor
return &theSingleInstance;
}
static T * Ptr;
};
#endif
<! -- myplugin.cc -->
#include "plugin.h"
namespace Plugins {
class MyPlugin : public Plugin {
public:
virtual void init() {
std::cerr << "MyPlugin::init" << std::endl;
}
};
};
REGISTER_PLUGIN("MyPlugin", Plugins::MyPlugin, MyPlugin);
<! -- plugin.cc -->
#include "plugin.h"
#include <dlfcn.h>
void PluginsManager::init() {
void *handle;
if((handle = ::dlopen("./myplugin.so",RTLD_NOW))==NULL) {
if (!handle) {
std::cerr << " !! " << dlerror() << std::endl;
::exit(EXIT_FAILURE);
}
}
};
bool PluginsManager::registerPlugin(const std::string & plugid, PluginPtr p)
{
std::cerr << "Registered '" << plugid << "'" << std::endl;
plugins_[plugid] = p;
return true;
};
PluginPtr PluginsManager::getPlugin(const std::string & plugid) {
PluginsMap::iterator i;
return ((i=plugins_.find(plugid)) == plugins_.end()) ? NULL : (*i).second;
};
template<>
PluginsManager *Singleton<PluginsManager>::Ptr = NULL;
<! -- test.cc -->
#include <iostream>
#include <map>
#include "plugin.h"
int main() {
PluginsManager::instance().init();
PluginsManager::instance().getPlugin("MyPlugin")->init();
}
<snip>
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]