Here is what I've done (I post a simplified code, but the idea is here).
The declaration file : pluginsmanager.h
Code: Select all
#include "pluginbase.h"
WX_DECLARE_OBJARRAY(PluginBase*, ArrayOfPlugins);
class PluginsManager
{
public:
PluginsManager();
virtual ~PluginsManager();
static PluginsManager& Get();
static void Kill();
int LoadPlugins(const wxString& appPath);
void UnloadPlugins();
private:
ArrayOfPlugins m_plugins;
static PluginsManager *m_instance;
}
Code: Select all
#include "pluginsmanager.h"
#include <wx/filename.h>
#include <wx/dynload.h>
#include <wx/dir.h>
PluginsManager* PluginsManager::m_instance=NULL;
#include <wx/arrimpl.cpp>
WX_DEFINE_OBJARRAY(ArrayOfPlugins);
PluginsManager::PluginsManager()
{
//
}
PluginsManager::~PluginsManager()
{
//
}
PluginsManager& PluginsManager::Get()
{
if (m_instance==NULL)
{
m_instance=new PluginsManager();
}
return *m_instance;
}
void PluginsManager::Kill()
{
if (m_instance!=NULL)
{
delete m_instance;
}
m_instance=NULL;
}
int PluginsManager::LoadPlugins(const wxString& appPath)
{
// The folder where we can find the plugins files (*.dll or *.so)
wxString sPlgPath=appPath;
sPlgPath << _T("Plugins") << wxFileName::GetPathSeparator();
wxDir dir(sPlgPath);
// If the folder does not exists, we get out of here
if (!wxDirExists(sPlgPath)) return 0;
if (!dir.IsOpened()) return 0;
wxString sFName;
#ifdef __WXMSW__
bool bRes=dir.GetFirst(&sFName, _T("*.dll"),wxDIR_FILES);
#else
bool bRes=dir.GetFirst(&sFName, _T("*.so"),wxDIR_FILES);
#endif
while(bRes)
{
//Loading the ".dll" or ".so" file using the wxPluginManager class
wxPluginManager::LoadLibrary(sPlgPath+sFName);
bRes=dir.GetNext(&sFName);
}
// Searching, in the loaded libraries, the instances of classes
// whitch name start with "wxTdlPlugin_"
wxHashTable_Node* node;
wxClassInfo::sm_classTable->BeginFind();
int iPlgCount=0;
while((node = wxClassInfo::sm_classTable->Next()))
{
wxClassInfo *classInfo = (wxClassInfo *)node->GetData();
wxString classname = classInfo->GetClassName();
if(classname.StartsWith(_T("wxTdlPlugin_")))
{
// Adding the founded instance to the plugins array
PluginBase *object = (PluginBase*)classInfo->CreateObject();
m_plugins.Add(object);
iPlgCount++;
}
}
return iPlgCount;
}
void PluginsManager::UnloadPlugins()
{
PluginBase *plg;
while(m_plugins.Count())
{
plg=*m_plugins.Detach(0);
delete plg;
}
}
Now, here is how to use it :
The plugins files (*.dll or *.so) are in a "plugins" sub-folder of the application.
In the "OnInit" method of the wxApp derived class, you'll have to call "PluginsManager::Get()" to initialize the manager.
Then, call the "LoadPlugins" method (with the app path as parameter). It will load all the ".dll" or ".so" files founded in the plugins subfolder, and create an instance of each classes of type "wxTdlPlugin_........" (and storing a pointer of each intance created in an array, for future use).
You can do the manager initialization and the plugins loading at the same time :
Code: Select all
PluginsManager::Get().LoadPlugins(TheAppPath);
Code: Select all
int MyApp::OnExit()
{
PluginsManager::Get().UnloadPlugins();
PluginsManager::Kill();
return wxApp::OnExit();
}
Feel free to ask for more details.
Regards
Xav'