   C++ Plugin System Architecture
  Hello and happy easter!I am currently studying physics and I have programmed a collection of visualisations of some of the topics we've covered in my first year physics course so far. I had the idea to create a single program and use a plugin architecture to for the visualisations. The main program has an mdi window and then the plugins create an mdi child window. So far my idea consists of a MainWindow which is responsible for creating the main user interface, a PluginLoader which loads DLL's from a 'plugin' folder and a PluginManager which is responsible for creating instances of the desired plugin. The main window is coded with the win32 api and the plugin loader uses LoadLibrary and GetProcAddress to load the required functions from the plugin DLL.My problem is how do i design the plugin system so that the plugin manager can communicate with each plugin effectively. What i mean by this is how do i structure my code to allow the plugin manager to be notified when the MDI child window of a plugin is closed etc..Thank you for your time. Any help will be appreciated.   
  You didn't specify what programming language you are using. My post assumes you are using C++ - if you are using, eg, C, then you will need to do some extra work to make this work for you (eg, replace classes with structs of function pointers).You could provide an abstract class (that is, a class with only pure-virtual methods) which you derive from inside your plugin. Then have the plugin export an initialization function which creates an instance of this class and returns a pointer to it (you probably want a termination function too, which deletes the instance, since afaik any memory allocated by the DLL must also be freed by the DLL).Similarly, you can have this class (or the exported functions) take a pointer to another abstract class as an argument and have your main program implement this class, create an instance and pass this instance to the plugin class/functions. Essentially an API object.The reason you use abstract pure-virtual classes is because you can pass pointers to these between DLL's and implement them in either the DLL or the main program and it will still work.Now that you have an instance of a class, you can communicate through methods. Heres some sample code to give you ideas:// In your plugin header file:class API {public:    // Write a message to a "log" panel in the main window    virtual void logMessage (const std::string& message)=0;    // ... whatever, define the API that the application provides to the plugins here};class Plugin {public:    // Generate data    virtual void run (API* api)=0;    // ... whatever, define the API that all plugins must provide to the application here};////////////////////////////////////////////////////////////////////////////////////////////////////// In the plugin:class MyPlugin : public Plugin {public:    void run (API* api)    {   api->logMessage("Generating some data in the plugin");    }};extern "C" DLL_EXPORT Plugin* initialize (){    return new MyPlugin();} extern "C" DLL_EXPORT void terminate (Plugin* plugin){    delete plugin;}////////////////////////////////////////////////////////////////////////////////////////////////////// In your application:class AppAPI : public API ......AppAPI api;// Plugin manager loads the plugin and retrieves the initialize and terminate functions...Plugin* plugin = initialize();// perhaps store this pointer in a list of plugins...plugin->run(&api);...// Then when doneterminate(plugin);I would probably pass the [font="Courier New"]API*[/font] to initialize and let the plugin cache the pointer, rather than passing it to every function. I would also probably wrap the plugin inside another class on the application side, which handles loading the dll, getting the function pointers to initialize and terminate and calling them appropriately (eg, calling terminate in the destructor).If you want to load multiple plugins at once and let them communicate between each other, you may also want to provide a messaging system. One way you could do this is create a Message class which you derive for different message types[1], provide a [font="Courier New"]send(Message* msg)[/font]  method which dispatches the messages to other plugins. The Plugin class then has a [font="Courier New"]messageReceived(const Message* msg)[/font] method which handles the message. You could then either dispatch the message to every other plugin, or give each plugin a name and allow messages to be sent to specific plugins ([font="Courier New"]send(const std::string& name, Message* msg)[/font] perhaps).  Be careful to make sure the DLL (or the application) that created the message also deletes it. One simple way would be something like this:// Some function in the plugin:{    MyMessage message;    message.parameter = 10;    api->send("receiver-name", message);    // message gets deallocated here because its on the stack}// The API implementation:void AppAPI::send (const std::string& name, Message& message){    for (std::vector<Plugin*>::iterator i = pluginVector.begin(); i != pluginVector.end(); ++i) {   Plugin* plugin = *i;   if (i->name() == name) { // Leave this out if you don't need it - or replace with something more flexible! (eg, plugins with multiple named "mailboxes"??)  i->messageReceived(&message);   }    }}In the above code, you do not need to worry about allocating or freeing the message objects, but you will have to be careful and never store the address of message inside the message handlers (but even if you new/delete message, you probably can't do this because you'll have no way to know when it should be deleted then - smart pointer won't work unless you roll your own that makes sure the DLL deletes it).I hope that gives you some ideas as to how you could solve this.[1] Of course, if you derive the message types from a base Message class, you will need to dynamic_cast the Message* to the correct class. Alternatively, since messages probably only contain data, you could just create a struct that has the appropriate fields for all messages. This would be nice and simple if all your messages look more or less the same, but if you want to pass complex data between plugins, it would probably be more flexible to derive from a Message class. Just make sure you check that dynamic_cast didn't return NULL (which would happen if a plugin gets passed a message type that it did not expect).   