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 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.
So the image below shows the basic structure of a plugin architecture using PPLS and classes.
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.
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.
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.
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.
Adding New Plugins
The steps for adding a new plugin are pretty simple.
- Create a new LabVIEW project and add the interface PPL.
- Create a new library with a class in it that inherits from the interface class that is inside the interface PPL.
- Create override VIs and implement your new feature.
- Build the lvlib into a PPL
- 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.