Home » C++

A Simple Plugin Architecture For C++

18 June 2003 131,502 views 6 Comments

A Simple Plugin Architecture For C++ continued…
The Server

To make things easier to manage, I have created two classes.

The first class is called "PluginDetails" and it stores the basic information about a single DLL plugin file. The second class is the "PluginManager" class, and it is used to create and store instances of the "PluginDetails" class. Both of these have been placed in the newly created files: "PluginManager.cpp" and "PluginManager.h" in the PluginServer application.

The "PluginDetails" class is quite simple. It basically consists of:

  • A function to create an instance of the plugin
  • Housekeeping functions for storing copies of strings
  • Class construction / destruction functions and initialisers
class PluginDetails
{
public:
   PluginDetails() { clearMembers(); }
        
   ~PluginDetails();

   PluginInterface * makeNewInstance();

   void setFileName(char * nm);
   char * getName() { return pluginName; }
   char * getType() { return pluginType; }
   void setName(char * nm);      
   void setType(char * nm);
      
private:
   void clearMembers()
   {
      pluginType=NULL;
      pluginName=NULL;
      filename=NULL;
      dllHandle=NULL;
   }

   char * filename;
   char * pluginType;
   char * pluginName;
   HINSTANCE dllHandle;
   PLUGIN_FACTORYFUNC funcHandle;      
};

The only part of this class worth going into more detail is the makeNewInstance( ) function, which is shown below.

PluginInterface * PluginDetails::makeNewInstance()
{
   if(!dllHandle) dllHandle = LoadLibrary(filename);

   if(dllHandle != NULL) 
   {            
      funcHandle = reinterpret_cast<PLUGIN_FACTORYFUNC>
                   (GetProcAddress(dllHandle, "makePlugin"));
      if(funcHandle != NULL)
      {
         return funcHandle();         
      }      
   }
   return NULL;
}

The first line loads the DLL plugin into memory as long as it hasn’t done so already on a previous call. It then attempts to retrieve the plugin’s factory function, and if successful, calls it to return a new instance of the plugin.

Once the instance has been retrieved, the Activate( ), Execute( ), and Destroy( ) functions can be called by the server using this pointer.

1 Star2 Stars3 Stars4 Stars5 Stars (4 votes, average: 4.00 out of 5)
Loading...

6 Comments »

  • Coder said:

    Hey, thanks for posting this example. Also thanks for posting the C++ source code examples, very helpful! 🙂

  • AndyN (author) said:

    Hey, no problem! This is an old one. I’m happy you and others are still getting some use from this 🙂

    Andy

  • Browner87 said:

    You don’t have any example of how to return pointers from a function. Is this possible using ANSI C++? Can you return a (char *) from the shared library to the main program?

  • AndyN (author) said:

    It’s been a long time since I’ve looked into this, but I’m pretty sure the answer’s no. I have a feeling that the dll and the main program don’t share memory space, and if you try to free memory that was allocated by the other, it’ll throw an error.

    If that’s the case, then the only way you could make this work would be to pass some sort of factory function to the plugin to allocate memory in the right place. That way the responsibility lies with the main process to free the memory later, plus it can safely unload the dll at any stage without memory leaks.

  • Browner87 said:

    Well, the pointer returning does work (it was other code that I had that was casing the problem). As for memory leaks, I don’t know. I found a better to achieve what I wanted so I only did it for experience.

    May I suggest that Linux programmers however read the following article if you are trying to implement this on Linux:
    http://www.linuxjournal.com/article/3687

  • AnhMV said:

    Thanks for this post