Programming modular applications in C++ (Part 2)

Programming

In the latest part of Programming modular applications in C++ I have shown you some practical examples of modular applications. These applications probably work well with your dedicated plugins. Problems begin when you try to mix in plugins written by your users which have been compiled using different compilers (it might work) or even operating systems (it cannot work!).

When it comes to real applications we can use this approach very rarely. We are guaranteed that dynamically linked shared libraries as plugins will work as they are expected only when we will compile them using the same version of compiler and operating system which we have used to produce application's binary file. Second restriction of approach which I have presented in last two articles (introduction and part 1) is that these programs work only on some systems compatibile with UNIX. When we need portable modular application we should take into account using dedicated library which provides portable interface. An example of such library is Poco::SharedLibrary. I'm going to write something about it later.

Any good solution?

Problems with writing portable shared libraries in C++ may have caused the development of libraries which port Python apps to C++ or interpreters for languages like JavaScript. Thanks to them we can write extensions in some higher level language which is portable by its nature and C++ will use them.

Best examples of using these solutions are web browsers from Mozilla and Google. Both of them have fair great collection of extensions written by developers from all corners of the world. Firefox and Chrome plugin's are written in JavaScript. Today browsers always have JavaScript engine, so using it in one more purpose is not a problem.

Mozilla created open source JavaScript parser engine called SpiderMonkey. Google also provides their solution called V8. JavaScript seems to be a good way to implement plugins interface.

Another great tool is Boost::Python library which provides tools to use C++ code in Python program and vice versa. Of course sometimes we have to write very fast and efficient code. In such cases JavaScript or even Python might not be good enough. We always have to consider which solution is optimal for us.

Problems with C++ plugins

I told you that C++ plugins may cause problems when we use different compilers to convert source code into binary files. Main cause of this problem are differences in Application Binary Interface which may be different in the same source code compiled by different compilers or even different versions of the same compiler. This problem is noticable in UNIX-like operating systems. Often used format called Executable and Linkable Format (ELF) becomes more and more popular what may result in better compatibility between applications compiled used different compilers which will use it by default. However there is always a risk that somebody will compile plugin with different compiler and ABI will be other than in application. And what if one day you decide that you will release your application for new operating system? New version will not be able to use plugins compiled for other os'. You will have to ask developers to compile their plugins for new platform. It may be difficult or even impossible.

The number of problems is less in case of open source software. When you release new version you just get source code of all plugins and compile them for new environment. It is easier but sometimes may be hard to do if there are thousands of plugins.

Really portable plugins

The best solution is to use one of interpreted language. Why it's the best way? Because you can always write own interpreter of this language and attach it to your software. You will probably be able to use one of existing interpreter. As I mentioned above there are at least two good languages which you can use to implement plugin interface in your software. I think that JavaScript is worse than Python. Python is more orderly and has a lot of built-in facilities which JS has not.

Java instead of C++?

What if plugins are not something exotic in your program but they are implemented as big parts of application with full rights? Maybe it is good reason why you should resign from C++ and use one of languages which has their own layer between 'executable code' and operating system. I mean Java and Python. This way is used by Eclipse. Eclipse is a platform written in Java. Bare Eclipse is useless. Its main functionalities are provided by plugins. If you want to write in C++, you use Eclipse CDT, for PHP you have Eclipse with different set of plugins. Last time I have seen Eclipse Arduino IDE. Eclipse can be run of every system which has its implementation of Java virtual machine.

In my opinion, better language is Python. It's also available on different platforms, but it is much faster. What's more you can compile its code to Java executable code (with Jython) which can be run on systems which has Java but has not Python (e.g. old mobile devices).

How to begin with POCO SharedLibrary?

Let's come back to C++. When we provide plugins compiled for different OS' by ourselves we can omit problem of differences in ABI. We can now take care of API (Application Programming Interface). In other words we should now think about programming parts of application in portable way from the code point of view. Well written code can be compiled without changes on all leading operating systems. We can use own library or depend on external libraries which provide interface for shared libraries. I've tested Poco::SharedLibrary component and I think it is good enough for a lot of purposes. It provides loaders for each different API of most popular operating systems.

POCO is very complex tool and well documented so I will not describe it in this article. I recommend using this presentation to get some information about this library and official documentation to extend your knowledge.

In next part of article dealing with modular programming I'm going to show you how to write application using Boost::Python.