C:SPL tutorials
From GDWiki
Contents |
[edit] 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!
[edit] 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 every application written in C/C++ to use your own plug-ins, 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 here for updates and more useful stuff regarding SPL.
[edit] 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 needed
- Buildable as static/shared library or DLL (only Win32)
- Various examples for all platforms explaining the development step by step
- Source code written in uniform style
[edit] 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 you can use optionally to speed up your plug-in development.
A plug-in consists of 4 simple C-functions, which all 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 "default-function" mean, you might ask now? A default-function is a simple function without any code in it. Since SPL requires these 4 functions in any case, you could use SPL's macros for implementing it. If you want to use one of these functions in a special way you want, just don't use the function-macro and implement that function for yourself.
For these 3 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 would have such a macro, the Run function would be implemented by default with no code, so the plug-in does nothing :-)
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 platforms, 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!
[edit] 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 ;-)
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 to hold the plug-in's information like name, version, build number, vendor etc., and 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 get it working, a simple example on how to implement a plug-in without all 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? You may notice that I don't use any "default-function" macros (except for the GetInfo function) in here, since I want to present how you can use all functions (again, except GetInfo) on your own.
"Hm, okay, sounds good, but when are all these functions called?" I hear you whisper ..that's a good question!
The reason why almost nobody would implement an own version of GetInfo is that this function basically does nothing else than returning a pointer to the plug-in information structure 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 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 included, too. Builds for Microsoft .NET 2003, Microsoft Visual Studio 6.0 and Linux (GCC) are included.

