Home » C++

A Simple Plugin Architecture For C++

18 June 2003 127,907 views 6 Comments

A Simple Plugin Architecture For C++ continued…
The plugin class

To create the plugin class you need to add a new Win32 Dynamic Link Library project to the solution. Call it "Plugin01", and direct the creation of the project to the same folder as the project for your main application (i.e. the DLL project is located at "/PluginServer/Plugin01/").

Make sure you set the build output directory of the DLL to the same output directory as your main application. (An easy way to do this in NET is to use a macro in the output directory setting for all your projects, e.g. for the debug configuration you would use "$(SolutionDir)Debug".)

If you’re not using NET, just make sure that your DLL is output to the same directory as the main application’s executable.

"Plugin01.cpp" should have been created automatically in your new DLL project. We also need a matching header file, so go ahead and add a new header file called "Plugin01.h" to your project. Copy the following code into the header file:

class Plugin01 : public PluginInterface
{
   public: 
      Plugin01();
      virtual ~Plugin01();

      int Activate();
      int Execute();
      int Destroy();
};

In "Plugin01.cpp", delete the "dllMain" function if it exists, and add the following code:

#include "../PluginInterface.h"
#include "Plugin01.h"

DECLARE_PLUGIN(Plugin01)
SET_PLUGIN_TYPE("Plugin01_Class")
SET_PLUGIN_NAME("Plugin01")

Plugin01::Plugin01()
{ 

}

Plugin01::~Plugin01()
{ 

}

int Plugin01::Activate()
{ 
   MessageBox(0,"Activate","Plugin01",MB_OK);  
   return 0;
}

int Plugin01::Execute()
{ 
   MessageBox(0,"Execute","Plugin01",MB_OK);  
   return 0;
}

int Plugin01::Destroy()
{ 
   MessageBox(0,"Destroy","Plugin01",MB_OK);  
   return 0;
}

A few points to note about compiling after this code addition:

  1. You may have other files #included into your "Plugin01.cpp" file, in which case don’t delete them. e.g. "stdafx.h"
  2. The path to include the file "PluginInterface.h" might need changing if you have set up your projects in a different arrangement to my specification at the top of the page.
  3. It’s unlikely, but you might need to include additional files for the function "MessageBox" to compile. Check your documentation on this function if you are having any problems. Alternatively, replace the MessageBox function with something else, since it is only used for illustrative purposes.

So far, you should have a completed plugin project that will compile to produce "Plugin01.dll" in your main application’s directory, and you should also have a header file called "PluginInterface.h" that describes the plugin interface.

The rest of the tutorial looks at how the main application deals with scanning and loading the plugins from the executable’s directory.

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