What is a plugin architecture?

What is a plugin architecture?

I wrote a previous post about ppl plugins and it occurred to me that maybe not everyone knows what a plugin architecture is. So I decided to clarify a little bit in case it wasn’t clear. I’m going to talk in terms of classes inside packed project libraries (PPLs), because that is the example I used in my previous article. There are other ways to do it. You can use VI references or you can uses classes without putting them in PPLs, but using classes inside PPLs seems to be the current standard, so I am going to go with that.

The Goal

The goal is to be able to add functionality to your program without rebuilding the executable. This allows the users of your program to extend it in ways that you, the developer haven’t envisioned. It makes your program much more flexible. Instead of coming to you for new features, you users can implement some new features themselves.

An example of this would be the QuickDrop or Tools Menu plugins in LabVIEW. Each of these extends the functionality of LabVIEW without needing to rebuild the LabVIEW executable. The user just creates some code that meets the requirements to be a plugin and puts it in the correct folder. LabVIEW finds that code and adds another QuickDrop shortcut or Tools menu option.

Basic Structure

So the image below shows the basic structure of a plugin architecture using PPLS and classes.

Here is the basic architecture diagram for a plugin system.

Note: this shows a plugin interface. Interfaces were added in LabVIEW 2020. You don’t need to use an interface, you could also just as easily use an abstract base class or even just a regular old class with class data and real methods with code in them. The key is that the executable relies on a class or interface inside a PPL that the end-user can create a child class of and override some methods.

The key is that the executable relies only on the interface. It doesn’t know anything about the User Supplied Plugins. Since the exe relies on the interface, you need to distribute your interface PPL and the executable together. The reason that the interface is in a PPL is so that it is easy for the User to create child classes. They can just add the PPL to their LabVIEW project and inherit from the interface.

Discovery

Because the exe doesn’t know anything about the user provided plugins, it needs a way to discover them. Any easy solution is to have a dedicated folder. Our exe can search for PPLs in this folder that contains a class that inherits from our interface. It can then provide a list of those for the user to choose. It could be a drop-down menu or ring control or some other method.

Example code for discovering plugins. It finds each PPL in a directory and then goes through each exported file to find a class that implements the interface. It returns the path to the class and the name of the PPL.

Loading

Once you have discovered the plugins, then you need a way to load them. This is actually really simple. You just use the load class default value then use to more specific class to get an interface class wire.

Simple factory pattern for loading a plugin.

Building the Interface PPL and exe

So when you are building your executable, the first thing is to build the interface into a PPL. I typically do that in a seperate LabVIEW Project. Then add that PPL to your main project and have your executable can depend on the PPL. Then you can build your executable and then any plugin classes. MGI Solution Explorer, which ships with LabVIEW (at least recent versions) can help with this. You can specify what order to build everything in.

MGI Solution Explorer showing build order. First build the Interface PPL – in case the source PPL, then the plugins and the executable.The key is building the interface first. The plugins and the executable can be built in parallel.

Adding New Plugins

The steps for adding a new plugin are pretty simple.

  1. Create a new LabVIEW project and add the interface PPL.
  2. Create a new library with a class in it that inherits from the interface class that is inside the interface PPL.
  3. Create override VIs and implement your new feature.
  4. Build the lvlib into a PPL
  5. Place the PPL into the correct folder so the exe can discover it.

If you want to learn how to build flexible, extendable plugin architectures like this for your project, we can help. Let’s talk.