The Challenge of Cross-Language Interoperability
CowboyRobot writes "David Chisnall of the University of Cambridge describes how interfacing between languages is increasingly important. You can no longer expect a nontrivial application to be written in a single language. High-level languages typically call code written in lower-level languages as part of their standard libraries (for example, GUI rendering), but adding calls can be difficult. In particular, interfaces between two languages that are not C are often difficult to construct. Even relatively simple examples, such as bridging between C++ and Java, are not typically handled automatically and require a C interface. The problem of interfacing between languages is going to become increasingly important to compiler writers over the coming years."
I don't even like .Net, but they won this round years ago.
What do you need multiple languages for anyway? Java does everything you could want. Java is a powerful, object-orientated, cross-platform language, with fully developed GUIs, such as Swing.
To demonstrate the superiority of Java, I can point to such leaders in their field as Eclipse, Minecraft, and this awesome applet I saw on someone's homepage once.
Anyone still using ancient and difficult to use languages such as C++ (let alone C!) are obviously crazy, and probably should be committed for their own good before they go on spree of shooting (not just themselves, but) other people in the foot. Java makes it almost impossible to shoot yourself, let alone others, in the foot.
Moreover, because Java is licensed under the GNU GPL, you can leverage the wisdom of crowds, and the powerful "many eyes make bugs shallow" concept to be confident that Java is the best.
And with just-in-time, Java is as fast as any other language, so you don't have to worry about the speed of execution. Instead, you can focus on developer time, and Java's just faster in that regard.
With built-in, from the ground up, support for Unicode, Java is there for the future, and is ready to be used across the multiverse (as soon as those aliens get their scripts into Unicode). Beat that C, with your lack of a string type.
And if you aren't convinced, tell me why do so many top enterprises use this language? You don't see ads from Fortune 500 companies looking for Ruby "developers" do you?
HELP MY ACCOUNT HAS BEEN HACKED BY AN ILLIBERAL ART STUDENT SET TO DESTROY THE INTERWEBZ!
The fault here lies specifically with Java and C++. Java's JNI is poorly designed and makes no serious attempt to make interoperability easy because it is against Java's philosophy. C++'s runtime is deliberately completely implementation dependent because C++'s designers thought that might let implementors squeeze out a little bit of performance.
Nevertheless, tools like Swig make even Java/C++ interoperation fairly easy, and many other languages try to accommodate C++ well (cf. Boost::Python).
Theoretically in a large organization with a huge and demanding application allowing developers to be able to interface with some sort of API with whatever language they choose may seem like a very flexible solution. I would be very worried that after a few years your code base would not only include a broad spectrum of languages but even potentially a broad spectrum of versions of those languages.
I suspect that you would find yourself having to learn Haskell for one emergency and Erlang for the next.
Where a multi language compatible API would be great though is when you start to migrate your system from one language to another. If you could do it piece by piece deploying each small well tested piece before moving on to the next I would suspect that many a disaster would be avoided.
Because C++ lets people automate resource management and error handling, things that in C are manual and error prone. C++ also provides standards for abstraction, encapsulation, and substitutability, something that in C is not standardized and handled differently by every library. Despite C++'s many flaws and unnecessary complexity, it still is a better language than C for many projects.
Use sockets. In majority of cases the performance is more than good enough, especially if designed properly, and you get network transparency "for free".
Sure there are cases where sockets are not appropriate, but IMHO they are far too seldom used.
On this aspect, Python does handle interoperability pretty well (at least with C and C++). It might just have a little bit too many options: .h-like file
* ctypes: connect to any C library directly (you just have to not do any mistake in parameters, as there is not check)
* Python C extention: write a wrapper in C.
* SWIG: "automatically" generates the wrapper, based on some
* cython: write C code using python syntax
Personally, I just use ctypes or cython, and it's quite easy to interpolate with any software library I need.
I just tried working with a codebase that had the same arrays storing both ints and pointers, and doing index arithmetic all over the place. The really horrifying thing was that it actually compiled 64bit, and just behaved differently.
Well, as Bill Clinton so eloquently said:
"It depends on what the meaning of the word ints ints"
Schroedinger's Brexit: The UK is both in and out of the EU at the same time!
WoW uses Lua, which is actually known for having a very simple and easy to use interface with C code. I even found an example on the Wikipedia page: http://en.wikipedia.org/wiki/Lua_(programming_language)#C_API
As someone who's done a fair bit of the reverse, and has recently needed to write C bindings for a few other languages (go, ruby), I thought this shouldn't be nearly so hard as you describe. Here's what I've come up with:
Example.cpp: Implements a class and C bindings for that class (The bindings could obviously be in a different file)
#include "ExampleCBindings.h"
#include
class Example {
public:
Example(int v) { value = v; std::cout << "New Example(" << v << ")\n"; }
~Example() { std::cout << "Deleting Example(" << value << ")\n"; }
int getValue() { return value; }
private:
int value;
};
extern "C" {
Example_class* newExample(int value) { return (Example_class*) new Example(value); }
void deleteExample(Example_class* example) { delete (Example*) example; }
int ExampleGetValue(Example_class* example) { return ((Example*) example).getValue(); };
}
ExampleCBindings.h: Public C bindings // what I love most is that Example_t never exists ;)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Example_t Example_class;
Example_class* newExample(int value);
void deleteExample(Example_class* example);
int ExampleGetValue(Example_class* example);
#ifdef __cplusplus
}
#endif
main.c: Simple C driver program that uses the api
#include "ExampleCBindings.h"
int main() {
Example_class * ex1 = newExample(5);
Example_class * ex2 = newExample(ExampleGetValue(ex1) + 2);
deleteExample(ex1);
deleteExample(ex2);
return 0;
}
Limitations include:
* Does not support objects existing on the stack. You're in C, this is the norm for opaque data structures.
* Need to individually wrap every function. Would need to create separate wrappers for overloaded functions, or write a variadic function that doesn't enforce types (Sigh, neither language supports reflection)
However, if you only wish to implement public functions, writing a script that autogenerates a wrapper like this would be fairly easy (I've done similar for a mocking framework for C code - now that's actually painful (not the script, inserting stubbed functions into a binary)). A little googling came up with a more formal attempt here.
I didn't sleep well. I'm tired and pissed off. Therefore a great distraction is to start a flame war!
He's a very good kernel engineer
Agreed.
and wrote a very good DVCS
Yes, bad user interfaces and mish-moshes of barely portable shell and C are the hallmarks of a good design. Mercurial is better, and has been chosen by most people/companies that have sat down and tried to make an objective comparison (e.g. Google, Fog Creek). Git is winning out mostly because it's what Linus, the ultimate cool kid, uses, and a lot of geeks still dream of sitting at the cool kids table.
But he's full of shit when it comes to C++. Not a single point of his stands up to any sort of logical scrutiny.
The one thing Linus does better than running the kernel project, is being an opinionated loudmouth. IIRC his hatred of C++ stem from an attempt in the ancient days of the kernel project to use it. At the time g++ seriously sucked. Small wonder it had problems. Or maybe Linus has a fear of objects because he was struck by one as a child, and doesn't like classes because he had to attend them (I said I didn't get much sleep).
Java is a bit of a nightmare for performance.
Citation needed.
Modern JVMs often out-perform even assembly language due to their ability to analyse and tune for the actual operating environment. Java routinely out-performs C - which like assembly produces static code that cannot automatically tune itself at run time. We're no longer doing interpreters with the old 10-to-1 performance differential that such environments were known for.
True, a small, trivial Java program will perform horribly relative to an equivalent non-VM language. The VM takes a lot of work to set up. But the primary employment for Java these days is in servers where the VM startup occurs maybe once a day or less and the initial massive performance hit is more than compensated for over the productive run time of the VM.
Shlaer-Mellor / Executable UML have been offering this type of language independence for over 20 years. The method works from business to embedded software. All that's required is model compiler support for the target language, which can be bought off the shelf or made in-house. Currently model compilers exist for C, C++, Java, Ada, System C, and I'm sure there's more that I haven't encountered.
I guess you missed this part: "he's right for the wrong reasons."
No, I saw it. He's wrong AND his reasons are crap.
I don't know why you're so defensive of the language.
I'm not. I use C++ a lot and I quite like it. If you have an open mind, I'll happily bore you to death with all the things I hate about C++ and why I wish they were better.
It is however impossible to have a sensible discussion about C++ with people who know almost nothing about it yet strongly hold opinions about it out of some misguided sense of fashion.
C++ hasn't exactly improved over the years.
Which is yet another statement which strongly indicates that you don't actually know anything about C++. If it turns out you do use it, then contratulations: you've managed to isolate yourself from reality.
Again, I could happily bore you with all the many things that have changed for better or worse up to 1998, between 1998 and 2011 and the merits and demerits of C++ 11 and C++14.
But you hold your opinions firmly and out of ignorance so it would be a complete waste of time on my part.
SJW n. One who posts facts.
When all's said and done, when you put power tools in the hands of the incompetent, you amplify their incompetence.
Most of the examples you listed weren't faults of Java, they're faults of the architects and people like that commit similar atrocities whether in Java, C, or VB. IBM mainframes were performing address-space hopscotch on CICS before Java was even born.
As for WebSphere, IBM isn't as ubiquitous as they used to be. Every few years I have to work with it. The rest of the time I have better tools at my disposal.
No, Java is not perfect. But it can be very effective when not wielded by clueless monkeys. The real problem isn't the language, it's the business attitude that all you need to develop complex systems is a handful of cheap monkeys.
Because some syntaxes are better at expressing some concepts while others are better at expressing other concepts.