Archived

This topic is now archived and is closed to further replies.

Crispy

std::map of function pointers from classes in dll's

Recommended Posts

Hi, I want to create an efficient plugin system that loads a number of dynamic link libraries and aquires a few function pointers that are then stored in a std::map, but I''m slightly confused how I should go about using the stored function pointers later on. Here''s the structure:
  
//base.h - supplied beforehand

class Base
{
   ... 
};
  
The plugin:
  
//derived.h - separate for each plugin;

//written by anyone who wants to write plugin;

//"derived" is a generic class name that denotes a more

//specific class, such as bitmap or whatever


//can I move these inside Derived somehow?

extern "C" const char* _export Register();
extern "C" const char* _export AquireFunctionName();

class Derived : public Base
{
   ...
 public:
   ...
   int Load(const char *);
   ...
};

//plugin.cpp


//called as the first thing when a dll is loaded

extern "C" const char* _export Register()
{
  return plugin_extension;  
}

//called to aquire the name of the Load function

extern "C" const char* _export AquireFunctionName()
{
  return "Derived::Load";
}

  
The plugin manager:
  
//the Derived::Load function pointer

typedef int (*FUNC_PluginFunc)(const char *);
//for DLL->AquireFunctionName and DLL->Register

typedef const char* (*FUNC_GetLoadFunc)();

typedef std::map<DWORD, FUNC_PluginFunc, std::less<DWORD> > TMap;
typedef TMap::value_type ValueType;

class Mgr
{
   TMap Map;
   //all objects loaded through plugins are stored here

   std::list<Base*>Objects;

 public:
   ...
   int LoadPlugins();  
   int Add(const char * pFileName);
   ...
};

int Mgr::LoadPlugins()
{
   //also aquires the file extension

   scan_target_folder_for_plugin_dlls_and_load_them(); 

   //simply convert the plugin extension to a DWORD

   DWORD HashValue = MAKEDWORD(plugin_file_extension);

   for_each_successfully_loaded_dll
    {
    register_plugin_by_calling_Register_in_the_dll();
    //aquire the actual address of "Derived::Load". Is this correct?

    FUNC_PluginFunc LoadFunc = GetProcAddres(module, GetProcAddress(module, "GetLoadFunc"));
    Map.insert(ValueType(HashValue, LoadFunc))
    }   
}

int Mgr::Add(const char * pFileName)
{
   TMap::iterator I = Map.find(aquire_extension(pFileName));

   //do error checking


   //what now? how do I add an appropriate object to the Objects list?

}
  
Hope I didn''t make any severe mistakes in the pseudocode and that it is at least a wee bit understandable. I personally feel that the whole structure is a bit off, but I can figure out a better way to do it. I''d appreciate some pointers, or a pseudocode example, if possible. Thanks in advance, Crispy

Share this post


Link to post
Share on other sites
What you need is a factory function in your dll, something like this:

  
extern "C" __declspec(dllexport) void GetPlugin( Base** plugin_object )
{
Derived* obj = new Derived;
// create function or whatever here

*plugin_object = dynamic_cast<Base*>(obj);
}


So from your main code you do:

  
Base* new_obj = NULL;
// get the plugin library, get the function address

GetPlugin( &new_obj );
// new_obj will now point to an instance of class Derived

// add new_obj to you manager



There is a bit more to it than this, have a look on flipcode for a recent article on plugins. The main catch is making sure that when delete is called to delete the instance of Derived it must be called from within the plugin, it cannot be called from within the core code otherwise it will more than likely crash.

hth

Paul

Share this post


Link to post
Share on other sites