Click here to Skip to main content
Click here to Skip to main content

Multi platform plug-in development made easy!

, 7 Mar 2006
Rate this:
Please Sign up or sign in to vote.
How to use and develop plug-ins for multiple platforms.

Introduction

Have you ever wondered how to develop plug-ins for multiple platforms like Windows and Linux with the same code? Then, you should take a closer look at the Simple Plug-in Layer (SPL) Library!

About this library

The SPL (Simple Plug-in Layer) library is an open source SDK (LGPL license) for plug-in development. With SPL, you can extend any application written in C/C++ to use your own plug-ins, the SPL will do all the managing, loading and unloading stuff for you. Additionally, the whole framework is fully multi-platform capable, so you don't have to develop multiple versions of the same plug-in for platforms provided by SPL.

This library was developed by Andreas Loeffler and René Stuhr. Please visit this site for updates and more useful stuff on SPL.

Features

  • Open source, uses LGPL license.
  • Free, costs absolutely nothing, even for commercial use.
  • Platform independent architecture.
  • Implementations for Linux and Win32 available, more platforms coming soon ...
  • Full Doxygen-/Javadoc-compatible documentation.
  • Optional macros for fast and easy plug-in development.
  • Variable plug-in arguments for extensible APIs.
  • Thread-safety for complex applications.
  • Uses STL library for stable and portable containers.
  • Object-oriented design, easy to extend.
  • Customizable to 32- or 64-bit systems.
  • Completely written in C++, no other dependencies except STL.
  • Can be built as static/shared library or DLL (only Win32).
  • Various examples for all the platforms explaining the development step by step.
  • Source code written in uniform style.

Overview

SPL is divided in two parts: Functions / classes for applications that want to use plug-ins, and the plug-in development side. The plug-in development side offers macros that you can use optionally to speed up your plug-in development.

A plug-in consists of four simple C-functions, all of which except one can be implemented as "default-functions" without any code behind it, using SPL's macros:

  • GetInfo
  • Initialize
  • Run (cannot be used as default-function)
  • Shutdown

What does a "default-function" mean? A default-function is a simple function without any code in it. Since SPL requires these four functions in any case, you can use SPL's macros for implementing it. If you want to use one of these functions in a special way , just don't use the function-macro and implement that function for yourself.

For these three functions, SPL uses the following macros:

SPL_IMPLEMENT_PLUGIN_GETINFO();
SPL_IMPLEMENT_PLUGIN_INITIALIZE();
SPL_IMPLEMENT_PLUGIN_SHUTDOWN();

So, why doesn't the Run function have such a macro? Hmmm, well, if we have such a macro, the Run function would be implemented by default with no code, so the plug-in does nothing Smile | :) .

Note: If you want to use/compile your plug-in with Windows, you need two additional macros provided by SPL, they're called:

SPL_DEFINE_PLUGIN_EXPORTS();
SPL_DEFINE_PLUGIN_DLLMAIN();

These two macros provide some Windows-specific code which is not used by other platforms like Linux, for example. Don't worry about it, you can put them safely into your plug-in, it does not matter if you want to compile/use your plug-in on Linux platform, SPL does all the stuff internally for you, so you won't have to change anything to compile and use your plug-ins on different platforms!

A "Hello-World" plug-in

Let's start with a very simple "Hello-World" plug-in. This example is also included in the SPL package. Our goal is a simple plug-in that compiles / runs on Windows and Linux, without doing any changes in the source code when "porting" it. Okay, actually you don't have to "port" anything Wink | ;-)

Have a look at the header file:

#if SPL_PLATFORM == SPL_PLATFORM_WIN32
 #include <windows.h>
#endif
SPL_DEFINE_PLUGIN_EXPORTS();
SPL_DEFINE_PLUGIN_INFO( 1,            ///< The build number.
    1,                                ///< The major version 
                                      ///(e.g. 1.xx). 
    0,                                ///< The minor version 
                                      ///(e.g. 0.10).
    true,                             ///< Does this plugin show its 
                                      ///arguments to the public?
    "plHelloWorld",                   ///< The plugin's name.
    "United Bytes",                   ///< The plugin's vendor.
    "Hello world, our first plugin!", ///< The plugin's general 
                                      ///description.
    "Simple test plugin! :-)",        ///< The plugin's additional 
                                      ///description.
    "http://www.unitedbytes.de",      ///< The plugin vendor's homepage.
    "info@unitedbytes.de",            ///< The plugin vendor's 
                                      ///email address.
    "ConsoleExampleAPI" );            ///< The plugin's UUID.

That's really all you need in your header file. We already discussed the SPL_DEFINE_PLUGIN_EXPORTS(); macro, so let's go to the macro:

SPL_DEFINE_PLUGIN_INFO();

This macro derives a class from slcPluginInfo, which is responsible for holding plug-in information like name, version, build number, vendor etc., and it creates a global instance called g_pluginInfo. This global object is required for all default-function macros of SPL.

Note for hardcore-coders: You don't need any of SPL's macros to make it working, a simple example on how to implement a plug-in without the macros is included in the SPL package.

Since our header file is now complete, let's step into our .cpp file:

#include "plHelloWorld.h"
SPL_DEFINE_PLUGIN_DLLMAIN();
SPL_IMPLEMENT_PLUGIN_GETINFO();
SPL_PLUGIN_API bool SPL_INIT_NAME_CODE( 
                   slcPluginArgs* a_pPluginArgs )
{
 printf( "HelloWorld: Hi there! Here " + 
         "we could initialize something!\n" );
 return true;
}
SPL_PLUGIN_API bool SPL_RUN_NAME_CODE( 
                   slcPluginArgs* a_pPluginArgs )
{
 printf( "HelloWorld: Hi, this is the plugin's " + 
                                "run function!\n" );
 return true;
}
SPL_PLUGIN_API bool SPL_SHUTDOWN_NAME_CODE( 
                          slcPluginArgs* a_pPluginArgs )
{
 printf( "HelloWorld: Bye, bye world, this " + 
                    "is the shutdown function.\n" );
 return true;
}

Looks very simple, doesn't it? I have not used any "default-function" macros (except for the GetInfo function) here, since I wanted to present how you can use all the functions (again, except GetInfo) on your own.

"Hm, okay, sounds good, but when are these functions called?" I hear you whisper ..that's a good question!

The reason why almost nobody would implement their own version of GetInfo is that this function basically does nothing other than returning a pointer to the plug-in information structure that we filled in the header by using the macro SPL_DEFINE_PLUGIN_INFO().

The Initialize function is called when a plug-in is successfully loaded, GetInfo is called manually from the user's code if he wants to get more information about the plug-in, Run contains the actual plug-in code, Shutdown is either called manually by the user if his program ends or it's done by the SPL's destructor to give all plug-ins a chance to clean themselves up.

Various examples using SPL are included in the SDK, a Doxygen-generated documentation for all parameters and functions is also included. Builds for Microsoft .NET 2003, Microsoft Visual Studio 6.0 and Linux (GCC) are also included.

Screenshot of the MFC example application

This screenshot shows an example application which is included in the SDK:

On the left side: our MFC example application showing all the loaded plug-ins and using the SPL library as DLL build. In the left list view, you see all the loaded plug-ins with the first plug-in selected. In the small window on the right, you see the information of the selected plug-in. You can modify a given text using the selected plug-in(s).

On the right side: the red line marks the example application itself. Beneath the line, you can see all the loaded plug-in processes.

Resources

Please visit here to get more information on this library.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Andreas Loeffler
Web Developer
Germany Germany
I was born in 1982 near Stuttgart / Germany and began my first steps in programming computers at the age of only nine years on an old Commodore CBM 7072. In 2002 I finished my education as IT specialist for software engineering and did my civillian service afterwards. Currently I'm working as leader of the software division in a bigger company located in south west Germany, mainly on software development and research projects for multimedia terminals and user recognition/verification systems.

Comments and Discussions

 
QuestionInternet Explorer Plugin Pinmemberpunkdrunkmonkey4-Nov-07 3:02 
QuestionIs this also usable on OSX? PinmemberstefkeB14-Mar-06 22:23 
AnswerRe: Is this also usable on OSX? PinmemberBuiZe15-Mar-06 7:18 
GeneralRe: Is this also usable on OSX? PinmemberAndreas Loeffler16-Mar-06 8:21 
GeneralYou're mixing runtime libraries in your examples PinmemberAmanjit Gill7-Mar-06 8:18 
GeneralRe: You're mixing runtime libraries in your examples PinmemberAndreas Loeffler16-Mar-06 8:27 
QuestionUsage PinmemberAnders Dalvander7-Mar-06 4:02 
AnswerRe: Usage PinmemberAndreas Loeffler16-Mar-06 8:25 
Generalvs2005 Pinmemberleven31-Jan-06 6:07 
GeneralRe: vs2005 PinmemberAndreas Loeffler4-Mar-06 4:25 
GeneralRe: vs2005 Pinmemberleven4-Mar-06 7:44 
GeneralRe: vs2005 PinmemberAmanjit Gill7-Mar-06 8:22 
GeneralCan you give some info about your platform sdk statement? PinmemberAmanjit Gill7-Mar-06 8:24 
GeneralRe: vs2005 Pinmemberrealsonic8-Oct-08 16:36 
GeneralHelp PinmemberAnshul Solanki1-Dec-05 19:55 
GeneralRe: Help PinmemberAndreas Loeffler4-Mar-06 4:21 
GeneralWOW!! Cool!! PinmemberTanzim Husain20-Jun-04 6:49 
GeneralRe: WOW!! Cool!! PinsussAndreas Loeffler21-Jun-04 22:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140827.1 | Last Updated 7 Mar 2006
Article Copyright 2004 by Andreas Loeffler
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid