Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using IPC to combine multiple languages

This is a general "noob" question about software design, so I apologise if it seems vague, but I would really appreciate the advice. Note the system described below is purely an example, not a specific product I have in mind.

I often have a need to combine the functionality of several libraries or utilities, written in different languages. For example, if I want to code a high-performance audio processing application for the desktop, I will write it in C / C++. Then, I want to add a nice GUI. But I don't want to learn Qt. I like the look and feel of Adobe Air, and would like to use that. Later, I have a need to access a USB device. But the USB library I have only has an API in Java. How can I combine all these elements together, to take advantage of their relative strengths?

Clearly, I cannot compile these various elements into one single executable. So I need to create and run them seperately, and give them a means to communicate. The most common way to do this seems to be using IPC (Inter Process Communication), eg shared memory or sockets. I prefer the idea of sockets, as the programs could potentially run on seperate machines on a network.

So I decide to create a local client / server system, with a custom API, to allow these elements to communicate. For example, the Air application will receive a message from the C application, telling it to update it's UI. The USB application running in Java will use the sockets to stream audio from the USB hardware, into the C application.

My question : is using local sockets in this way a typical way to design such a system? Will the performance be much worse than a truly native application (e.g. everything in Java or C, in a single executable) ? It also seems likely that such an approach would be prone to bugs, and difficult to maintain?

I frequently find myself coming up against the limits of existing software libraries (e.g. a graphics library with a pretty, flexible UI but no way to access low-level hardware, or a media library that can mix many audio streams, but has no support for video playback), and find it very frustrating. If anyone could advise the best way to combine arbitrary software libraries like this, I would really appreciate it.

Thanks in advance!

like image 852
darasan Avatar asked Aug 02 '12 05:08

darasan


People also ask

Can you combine multiple programming languages?

It is possible to combine different languages in one project, you just write two different programmes and let them communicate with each other. And in some cases it even makes sense. Say your project is written in Java or Python for the most part but you have a part that requires a little more computing power.

How do 2 coding languages work together?

In the simple case, different languages are compiled to the same code. For example, C and C++ code typically is compiled into machine assembler or C# and VB.Net is compiled into IL (the language understood by the . NET runtime). It gets more difficult if the languages/compilers use a differnt type system.

Can you use multiple coding languages in one project?

Some languages are great for one task but not another, so working with multiple programming languages enables developers to use the right tool for the job. In this way, all development is polyglot; it's just the nature of the beast.

What is a polyglot application?

Polyglot programming is the practice of writing code in multiple languages to capture additional functionality and efficiency not available in a single language. The use of domain specific languages (DSLs) has become a standard practice for enterprise application development.


1 Answers

As you have correctly identified, combining libraries from different language or platforms is hard. There are several ways to do it, but none are ideal. Examples:

  • Native call interfaces (e.g. JNI / JNA) - very fast but tricky to make work correctly, and you have the problem that the data types used typically don't map cleanly across different platforms. Adds native dependencies.
  • Socket based IPC with text protocol (XML, JSON, etc) - works OK and common formats are likely to be supported at both ends, but adds a lot of overhead. Can be a pain to maintain custom schema mappings etc.
  • Socket based IPC with binary protocol (e.g. Google protocol buffers) - quite efficient, needs a lot of work to get a custom protocol working correctly on both ends
  • Communication via a 3rd system (e.g. database, message queue, filesystem) - lots of overhead, can get fragile, introduces a major dependency on a 3rd system.

In my experience, it usually isn't worth integrating a new language / platform just to get one specific library or feature. Take your user interface example - no matter how nice Adobe Air looks, I doubt it is worth trying to integrate it with an existing C/C++ application.

Even if you get it to work, it will significantly complicate the future maintenance and devlopment of your application. Builds become more complex. You need to maintain additional communication / "glue" code. You need to manage more dependencies. Your users will get hit by many more configuration issues. Testing becomes more difficult. It becomes harder to teach someone new about how the whole system works. You need to maintain your skills in more languages / frameworks etc.

I'd recommend the following strategy:

  1. Pick a primary platform
  2. Whenever you need a new library or feature, look for something on your primary platform first. Hopefully (usually?) there is something good available - but even if not then it might be worth coding something yourself if the requirement is quite small.
  3. Only if there is no reasonable option on the primary platform, then you can start to think about integrating a new language/platform

In terms of primary platform, I'd normally suggest a JVM language like Java, Scala or Clojure since the JVM is very well engineered, offers great performance, is highly portable and has the largest / most cohesive library ecosystem (most of which is open source). The JVM is therefore probably the best "general purpose" choice unless you have some very specific requirement which is unlikely to be possible on the JVM, e.g.:

  • If you are doing lots of embedded / realtime / systems programming wthat requires hardware access you probably need to go for C/C++
  • If you are coding purely for web-based clients, you probably want to use JavaScript (if you are also writing code on the server side you can consider JavaScript code generation frameworks/libraries that can work on the JVM, e.g. Vaadin or ClojureScript)
like image 128
mikera Avatar answered Sep 28 '22 09:09

mikera