C++ plugins in QGIS
Most QGIS plugins are written in Python. The QGIS Python API is powerful and the possibilities for creating plugins are extensive. There is however another, less well-known and used option — C++ plugins. Some of you might have used one without realizing it, the Geometry Checker and OfflineEditing are included in QGIS installations as core plugins and are written in C++.
So, let’s explore this world of C++ plugins and see how they work, how they differ from Python plugins and what are their advantages and disadvantages.
Short prologue on some programming concepts
Here I am going to explain some basic things about programming, hopefully in a way that is not too technical, just so we’re on the same page going forward.
If you have experience in programming you might want to skip to the section titled How C++ plugins work
What is programming anyway?
So, to start all the way from the basics, what even is programming? A program can be defined as a sequence of instructions for your computer to execute. Computers deal with numbers in the binary system so a program is basically a bunch of ones and zeroes that sit on your computer’s hard drive and can then be executed after which (typically) your operating system mediates the running of your program.
Programming then is the process of writing a program. So how does one do that? Do you just manually enter those ones and zeroes somewhere? That would seem difficult, right? Well, this is what programming initially was, people wrote code in raw binary. This binary format of code that can be executed by a computer is called machine code. Writing programs this way is obviously cumbersome and rarely done nowadays.
This is where programming languages come in. They are a way for people to use an agreed-upon notation to write programs in a format that is easier for humans to understand. However code written in a programming language really on its own is really just a bunch of text files that your computer cannot really do anything with. You still need a way to get the code into a format that can actually be executed by your machine.
Compiled and interpreted languages
To achieve this there are two different approaches, compiled and interpreted programming languages. C++ is a compiled language. This means that you use a type of program (called a compiler) to compile your C++ code into machine code. As a result you get an executable binary file or a library (more on this later). Windows users might be familiar with the .exe file extension, which denotes that a file is executable. On Linux and MacOS executables don’t have a file extension.
In contrast Python is an interpreted language which means that you have a type of program called an interpreter that in simple terms goes through your source code and executes it line by line. The way compilers and interpreters work is of course a lot more complicated and varied, but this is the rough distinction between the two.
Shared libraries
A library is a different format of compiled machine code which, unlike executables, cannot be executed on its own. In C++ there are two types of libraries, static and shared although here shared libraries are mostly relevant. You might’ve come across them already, on Windows they’re known as .dll (Dynamically Linked Library) files. Common file extensions for shared libraries on other operating systems are .so (e.g. Linux and MacOS) and .dylib (MacOS) files.
Once you have compiled a shared library you can link an executable program against this library. This means that you can use code from the library in your program. The code is loaded as needed by the executable program. Parenthetically if you’ve ever experienced some issue with missing DLL files, this is why — many programs expect a shared library to exist at some location.
How C++ plugins work
As we’ve learned Python code is executed by an interpreter, which is part of the QGIS installation (on Windows and MacOS). When installing a Python plugin its source code is copied to your QGIS profile’s folder and then used by the interpreter.
As for C++ plugins there is no such interpreter and the code has to be compiled into machine code. Based on the last section the solution hopefully becomes clear — you have to compile your plugin as a shared library. The library can then be loaded by QGIS and its code executed as intended.
You can either copy this shared library to an operating system specific folder that QGIS looks in, or you can tell QGIS to look in some other folder of your choosing. In Settings > Options > System you have a section called Plugin Paths where you can add a folder containing your shared library. After this the plugin should show up in the QGIS plugin manager and can be activated.
Why use C++ and why not?
Now that we know the basic idea behind C++ plugins, let’s talk about the reasons you might want to make one instead of a Python plugin and vice versa. C++ as a programming language can be quite divisive as I suppose many other (if not all) languages. Personally I really like C++ but even still I think it has to be acknowledged right off the bat that Python plugins have a lot of advantages over C++ plugins.
The case for Python plugins
Python plugins are going to be more stable and you can expect the same plugin code to work more or less the same across different QGIS versions. This is not the case with C++ and a plugin compiled using a specific QGIS version’s development libraries is unlikely to work with other versions.
There’s also the issue of compatibility between operating systems. Python code will be handled by an interpreter that will execute the code properly in the given environment. In order to provide a C++ plugin for different platforms you need to compile the plugin targeting each platform separately in addition to potentially having to provide versions of your plugin for different QGIS versions.
So a C++ plugin will require more work keeping up with different platforms and versions. Of course these processes can (and should) be automated which helps and also it’s not as if you are required to support every operating system and QGIS version. Overall maintaining plugin builds still likely requires more effort, especially to begin with.
Another advantage for Python here is installation, you can distribute a Python plugin from the OSGeo plugin repository and most users will be familiar with the installation process. Not that installing C++ plugins is extremely difficult, but it can be less convenient.
Generally speaking it’s likely that you’re going to have an easier time writing Python plugins as there is more documentation about it and more people doing (and therefore discussing) it. Python is a more approachable language and therefore probably easier to start with. Also depending on the type of plugin you’re writing some of Python’s features may be more convenient for the task.
The case for C++ plugins
The biggest reason to go with C++ is performance. Interpreted languages like Python generally speaking are slower (although the gap has been closing). There are ways to improve Python’s performance but C++ is still likely to be faster (obviously assuming you’re actually writing performant code). So this is the main reason you’d want to choose C++ over Python. If your plugin needs to do a lot of work and do it fast C++ will likely have the advantage.
If the point is to just get a plugin out and high performance is not a requirement then you probably should just go with Python. However if you’re more interested in the subject and have a personal preference for C++ it might be more motivating to choose it. As QGIS is written in C++ writing a plugin in the same language using its libraries might also be a stepping stone to get into contributing to QGIS itself.
Let’s say you need a performance-intensive plugin that you know would be mainly used in some organization where everyone is required to use one operating system and QGIS is updated with each LTR version, which would eliminate a lot of the effort of maintaining different builds of your plugin. I think a case like this would be quite well suited for a C++ plugin.
Conclusions
I hope this has been an interesting introduction to this subject and I hope you understand how plugins work within QGIS a bit better now!
Did you get interested in developing a C++ plugin? Covering the specifics of that is a bit outside the scope of this post, but I would recommend looking at this excellent example plugin on GitHub. It has great information to help you get started. To be clear, we’re not involved in the repository in any way — I just came across it while researching the subject and found it very helpful!