Sunday, November 2, 2014

Creating Basic C++ Plugins (Part 2 of 3)

In the first part of this tutorial, we covered the basic setup of what it takes to start on a plugin system in C++. This meant getting used to function calling conventions, why they matter, and how they apply to executables vs libraries. Part 1 then went on to create the basic API that will be used throughout the remainder of the tutorial. Part 2 will now go over some skeleton code to contain a handle to a shared library (using RAII), then walk through a method to load and verify a library at runtime.

*Make sure you have SDL2 installed before continuing.

Part 2:

If it weren't for RAII, I would likely used C for most of my projects instead of C++. RAII will help with this tutorial by performing automatic unloading of resources from a shared library once all handles to it go our of scope by means of class destructor. Using this concept in our tutorial means wrapping all shared library loading from SDL2 into a class object and providing it ways to unload resources through a destructor. In addition, this wrapper class will contain extensions to grab a pointer to a plugin object (from part 1) and retrieve it for use later. Let's get started:

Creating the Shared Library Wrapper Class:

Let's start with a "shared library" class. The header file for it will contain the class declaration, along with all methods used throughout the tutorial. I've added some brief comments in order to specify what each method does, The header file from the first tutorial is specified as "pluginAPI.h".


I've removed the copy constructor and copy operator in order to keep some aspects of this code short. You can always add copy functionality at a later time, but keep in mind that you must also add a way to share references to the same library. By this, I mean that if a handle to a library is shared by more than one class instance, it will be deleted by both instances and cause your program to crash (an std::shared_ptr may assist in this. Also, if you want copies, make sure that your plugin object (see part 3) supports it.


As you can see, the implementation is pretty simple. only a few error-checking methods and we've successfully wrapped the shared library functionality from SDL into a wrapper class and allowed ourselves the ability to load plugins from the dynamic libraries.

Loading a Plugin at Runtime

With everything shown so far, we can immediately start on an example system which will load data at runtime, validate it, then execute it.
The sample program below takes parameters from main() and passes them into a function called "loadSharedLibs()." This helper function scans all referenced character strings and checks to make sure that they are valid paths to shared libraries. If so, then the function will attempt to load a shared library from each of the input paths. All successfully loaded libraries are added to a list, then returned to main(). Once main() has its list of plugins from the libraries, it runs them.

Success! All that's left is to create a custom plugin and load it into the program above. Check out part 3 for the details.

No comments:

Post a Comment