C:SPL tutorials
From GPWiki
The wiki is now hosted by GameDev.NET at wiki.gamedev.net. All gpwiki.org content has been moved to the new server. However, the GPWiki forums are still active! Come say hello.
[edit] IntroductionHave 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 LibraryThe 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
[edit] OverviewSPL 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-inLet'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:
#include <windows.h>
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!
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. Categories: C | Tutorial |


