A Simple Plug-In Example
Volume Number: 14
Issue Number: 6
Column Tag: Plugging In
by Joe Zobkiw
How to add plug-in support to your application
If you've ever used Adobe Photoshop, HyperCard, or even the latest version of
Metrowerks' CodeWarrior you've made use of plug-in technology. Plug-ins are simply
executable code (and resources) that reside in a file other than that of the application
itself. Applications can load plug-ins dynamically at run-time and benefit from the
functionality they provide.
For example, Photoshop is a high-end graphics application that allows you to load an
image and manipulate it in any of a number of interesting ways. You can add a
drop-shadow, change the color balance, produce lighting effects, and more by using
special. Much of this functionality is provided by plug-ins, known in this case as
Photoshop Filters. When you launch the Photoshop application, it scans a folder in the
same folder as itself named "Plug-ins" for files of a specific type. As it finds these
files it makes their functionality available from within the program by displaying
them in the Filters menu. Selecting items from this menu invoke the appropriate
plug-in and extend the capabilities of Photoshop.
You might ask yourself, why would anyone want to write dozens of separate plug-ins if
they are just going to be used from within an application anyway? The reasons are
simple. By extracting certain functionality into plug-ins, you can easily update or add
new features to an application without changing the application itself. For instance, to
add a new filter to Photoshop, you simply drag it into the Plug-ins folder and relaunch
the application. This not only allows Adobe to easily manage their software, but it also
allows hundreds of third-party developers to enhance and customize the Photoshop
application by writing Photoshop Filters to the Adobe-published specification, all
without having access to the source code of Photoshop itself.
Given these examples, you can see that using plug-ins can not only help ease the
burden of development, but it can also help your salespeople by making your
application more accessible, more customizable, and more appealing to your
customers. Let's look at an example of how you might implement plug-in support in
your application.
Basic Plug-in Support
The following example shows you the most basic steps required to implement plug-in
support in an application. We have implemented a simple PowerPC application that
loads a special plug-in, in our case compiled as a PowerPC shared library, and
executes code within it. Once you understand how this application and plug-in work
together, you can easily extend the sample and devise your own plug-in architecture
for your application.
Figure 1.
For this project we are using CodeWarrior Professional Release 2. Our shared library
is written in C and our application is C++. We started out by creating a single project
file that contains both targets for this project, the application and the shared library.
The project is set up so whenever we build the application, the shared library will be
brought up to date if need be. You do not need to have both of your targets in the same
project file. However, CodeWarrior Professional Release 2 allows us to do this and it
makes it easier for this particular project.
Figure 2.
Before you design an application to call a plug-in you must decide on the calling
conventions. In this simple case we have decided to implement a single function in our
shared library that will be called from the application. We are calling our function
DisplayDialogAndBeep. It is called with one parameter, inBeepTimes, which
represents the number of times to make the computer beep while displaying a dialog. It
is defined as follows:
Listing 1.
OSErr DisplayDialogAndBeep(long inBeepTimes);
When the project builds both the application and the shared library, it produces two
files. One is an application program named "Application" and the other is a shared
library named "Shared Library." When the application is launched, it prompts the
user to enter a value for inBeepTimes. Upon entering this value, the application
attempts to open the shared library by name, find the exported DisplayDialogAndBeep
function by name, and call the function. If these steps are completed successfully, the