Slashdot Mirror


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."

36 of 286 comments (clear)

  1. Cross language - what .Net gets right by cstec · · Score: 4, Insightful

    I don't even like .Net, but they won this round years ago.

    1. Re:Cross language - what .Net gets right by Darinbob · · Score: 2, Informative

      This was one years before then, it used to be normal to be cross language. Ie, VMS was implemented in a variety of languages, Unix provided a common calling standard between languages, etc.

    2. Re:Cross language - what .Net gets right by gigaherz · · Score: 4, Informative

      Not true. .NET assemblies are able to use both standard exports (C functions), and COM libraries (which can be coded in C, C++, VisualBasic 6, ...), and can also export COM interfaces to the .NET classes and through the use of assembly modification tools, also export C functions.

    3. Re:Cross language - what .Net gets right by rnturn · · Score: 3, Informative

      ``VMS was implemented in a variety of languages''

      (Hmm... I thought the lion's share (if not all) of VMS was written in BLISS.)

      You could definitely call, say, a VAX BASIC routine from a VAX FORTRAN program, VAX FORTRAN subroutines from VAX C programs, etc. And you didn't have to jump through a bunch of hoops to do it, either.

      --
      CUR ALLOC 20195.....5804M
    4. Re:Cross language - what .Net gets right by Pinhedd · · Score: 2, Interesting

      .NET is already an extremely verbose platform that is many years ahead of its competition. If it seems like they've neglected it a bit that may be because there's currently either no motivation to add new features to it, or there's currently not enough features worth adding to it that would justify an incremental release and all of the accompanying documentation. I'd rather that they take a step back, let it mature a bit, and clean things up a bit if necessary.

    5. Re:Cross language - what .Net gets right by WinstonWolfIT · · Score: 2

      .NET backend + javascript front end, job done. It's mature, feature complete almost to exhaustion, and turns modern-day developers to focus on business requirements and integration.

    6. Re:Cross language - what .Net gets right by Dahamma · · Score: 4, Insightful

      .NET is already an extremely verbose platform that is many years ahead of its competition

      Wha? Its "competition" for what, exactly? Windows apps? So, wait, you are telling me a Microsoft development platform is ahead of its competition for developing Windows apps? And how is that interesting?

    7. Re:Cross language - what .Net gets right by cardpuncher · · Score: 4, Informative

      VMS was mostly written in BLISS, although there were chunks of Macro-32, particularly in the drivers. The big challenge in the Alpha port was effectively cross-compiling the Macro-32 code for Alpha hardware. Towards the end of Digital as an independent company, more development work was done in C.

      An early decision in the design of VAX/VMS was the definition of the "VAX Procedure Calling Standard" that dictated the instructions and mechanisms to be used for calling procedures, passing parameters and returning values, independent of language. All the compilers were expected to use this mechanism so that you could, for example, call a procedure written in VAX COBOL from VAX FORTRAN. This worked to a large extent, but it wasn't explicitly defined (and couldn't really be defined) whether compilers should use call-by-value, call-by-reference or call-by-descriptor for particular data types so additional semantic cruft was required to sort out the deails of parameter-passing. VAX C would sometimes pass a double-word argument in violation of the standard. The standard also had nothing to say about meta issues like run time initialisation, memory and thread usage, etc.

      That said, it was a revelation coming from an IBM world in which you'd sometimes have to write Assembler shims to patch up the calling conventions if you needed to get one language talking to another.

    8. Re:Cross language - what .Net gets right by TheRaven64 · · Score: 4, Insightful

      I talk a bit about .NET in TFA. It does some things right, but it still struggles with things like mutability. If you use F#, you get a language that is a lot like OCaml, and if you use it like OCaml, then it's fine. When you start trying to integrate with C#, then you find that they have different concepts of mutability. And you have to do it because the F# collection classes are much slower than their C# counterparts because the CLR lacks most of the optimisations that a typical OCaml implementation has to elide copies of immutable structures when your operation is implicitly destructive.

      --
      I am TheRaven on Soylent News
    9. Re:Cross language - what .Net gets right by TheRaven64 · · Score: 4, Informative

      VMS managed to get the idea of the platform ABI specifying procedure call conventions right very early on. It had quite an easy job though. C, BASIC and Fortran are all structured programming languages with basically the same set of primitive types. None of them have (or, in the VMS days, had) classes, late binding, or real garbage collection. BASIC is kind-of GC'd, but it doesn't have pointers and so everything passed across the language barrier from BASIC was by value, so the GC didn't have to do anything clever.

      It's worth remembering that when VMS was introduced, other platforms were still having problems getting C and Pascal to play nicely together (Pascal pushing arguments onto the stack in the opposite order to C), so that's not to belittle the achievement of VMS, but it's a very different world now that we have Simula and Smalltalk families of object orientation, various branches of functional languages, languages like Go and Erlang with (very different) first-class parallelism, and so on.

      --
      I am TheRaven on Soylent News
    10. Re:Cross language - what .Net gets right by Guy+Harris · · Score: 3, Insightful

      Passing in registers is not a standard C parameter passing method

      There's no such thing as "a standard C parameter passing method". Passing in registers is a perfectly legitimate C parameter passing method, used on several RISC architectures, such as SPARC, MIPS, 32-bit ARM, 64-bit ARM, and 64-bit {PowerPC/Power Architecture} (and probably most other RISC architectures), as well as x86-64 and z/Architecture.

      If there are more parameters than fit in the registers available for parameter passing, or if the parameters are in the variable-length portion of the argument list, they might be passed on the stack, and if the called function has no prototype in scope, the compiler might be forced to pass everything on the stack, but, in all other cases, if the ABI supports it, parameters can and will be passed on the stack.

    11. Re:Cross language - what .Net gets right by ebno-10db · · Score: 2

      many of the VMS commands and utilities were written in a mish mash of languages, as if each programmer just chose what they wanted to use

      If they chose languages that were better for the task at hand than others, that sounds like a good approach. VAX cross-language compatibility made it practical.

      BLISS and Fortran and Macro-32 all in the same program.

      Mixing BLISS and Macro-32 is hardly a kluge, but what utility mixed them with Fortran?

      There was also a data description language added to the mix to allow sharing data structures across languages.

      Another excellent idea, supporting cross-language operation.

      Between VMS and Alpha DEC manage to prove the old adage: if you build a better mousetrap, your company will go down the toilet. More recent companies learned from that, and avoid well thought out designs.

    12. Re:Cross language - what .Net gets right by gbjbaanb · · Score: 3, Insightful

      don't - although the COM interop tooling for VB.NET is quite good, its all a massive performance penalty, and isn't quite as nice as its presented. The cross environment marshalling that's required (plus some pinning of data so the garbage collector becomes less efficient) means its there for convenience only. You wouldn't want to use it for heavy applications.

      Microsoft wants you to rewrite in .net (well, then they did, now they want you to rewrite it all in WinRT).

    13. Re:Cross language - what .Net gets right by raddan · · Score: 3, Informative

      P/Invoke, the other interop mechanism alluded to by the poster, is substantially faster than COM interop. I spent a summer at Microsoft Research investigating ways to make interop for .NET faster. There's maybe 20 or so cycles of overhead for P/Invoke, which is practically free from a performance standpoint. In addition to having its own [reference-counting] garbage collector, COM has extensive automatic-marshaling capabilities. These things make interop easy, but they add substantial overhead compared to P/Invoke. On the other hand, P/Invoke is somewhat painful to use, particularly if you want to avoid marshaling overheads and play nice with .NET's [tracing] garbage collector and managed type system. P/Invoke will often happily accept your ginned-up type signatures and then fail at runtime. Ouch.

      Coming from the Java world, I was totally blown away by what .NET can do. I can't speak for Microsoft myself, but I would be very surprised if .NET was not going to stick around for a long time. With the exception of perhaps Haskell, the .NET runtime is probably the most advanced managed runtime available to ordinary programmers (i.e., non-researchers). And, with some small exceptions (BigInteger performance... GRRR!), Mono is a close second. What the Scala compiler is capable of squeezing out of the poor, little JVM is astonishing, but Scala's performance is often bad in surprising ways, largely due to workarounds for shortcomings in the JVM's type system.

    14. Re:Cross language - what .Net gets right by shutdown+-p+now · · Score: 2

      The cross environment marshalling that's required (plus some pinning of data so the garbage collector becomes less efficient) means its there for convenience only. You wouldn't want to use it for heavy applications.

      That isn't really true. Most of Microsoft's own "heavy applications" use it, heavily in fact. Both Office and Visual Studio use it a lot, especially the latter.

      Yes, it's slower than .NET-to-.NET, much less native-to-native. But any bridge is going to introduce overhead, when either side speaks a different language, utilizes different data structures etc. In that sense, P/Invoke is actually pretty slim, because so long as you use "blittable types", i.e. primitives and structs thereof - basically things that have the same bit representation in .NET as they do in native - calls are direct, with no marshaling overhead at all, it's literally a CALL instruction emitted by the JIT.

  2. Java, all you need. by magic+maverick+ · · Score: 5, Funny

    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!
    1. Re:Java, all you need. by Dahamma · · Score: 4, Insightful

      Clearly there is some sarcasm/irony, as "What do you need multiple languages for anyway?", "and this awesome applet I saw on someone's homepage once" is pretty clear (unless he's a moron).

      But honestly the 80% of the rest of his points are actually true about Java - so either he doesn't really understand irony, he doesn't really understand Java, or he is just trying (rather successfully, IMO) to troll slashdot. I'm hoping that last case, in which I salute his efforts :)

    2. Re:Java, all you need. by mjwalshe · · Score: 2

      you win the inter webs this week for "Java is portable in the same sense that you'd be portable if you traveled with your own hotel."

  3. Java, C++ by stenvar · · Score: 4, Informative

    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).

    1. Re:Java, C++ by serviscope_minor · · Score: 3, Insightful

      Java's JNI is poorly designed and makes no serious attempt to make interoperability easy because it is against Java's philosophy

      I'm not an expert but I've done a bit of native language binding now and again. I didn't find JNI a massive barrel of laughs, but I didn't find it notably worse than other native bindings (e.g. CPython, ...). I was able to make calls in and out and throw java exceptions etc etc easily enough.

      Can you be more specific without reference to higher level wrapper tools (e.g. Boost:Python) since those aren't really part of the languages.

      C++'s runtime is deliberately completely implementation dependent because C++'s designers thought that might let implementors squeeze out a little bit of performance.

      They made the right choice here. C++ compiles have come on an awfully long way since the beginning. One of the biggest parts of the runtime (exceptions) have gone from slow and painful to essentially zero cost if you never use them. That ould never have happened if the rnutime was heavily specified.

      Besides, C++ is too portable for uch specification not to be quite harmful.

      --
      SJW n. One who posts facts.
    2. Re:Java, C++ by RabidReindeer · · Score: 2

      Part of the problem is that Java refuses to provide unsafe primitives in the Java language itself, for no good reason.

      There's a reason. Java wasn't designed to be unsafe. It exerts a lot of effort to avoid being unsafe, which is why things like buffer overflows are not routine exploits in Java code. It also takes the "write once/run anywhere" concept very, very seriously. Once you reach the JNI level, of course, all bets are off, but again, Java is primarily self-contained.

      If these features are an impediment, Java isn't the best platform to be using.

    3. Re:Java, C++ by serviscope_minor · · Score: 2

      In Python and other HLLs, you can do all the C binding in the HLL itself,

      If by that you mean something like CTypes in Python, the same existst in Java too: JNA.

      you need to distribute an extra native code library.

      Yes, but that's not always a big problem. I've only ever used JNI to interface to a big blob of C++ code that I wrote in C++ for speed (and because it's a nicer language for this sort of thing than Java). In that case, the binary has to be distributed no matter what the host language.

      Really? For every single feature in the language that's unspecified, leaving it unspecified and up to the implementation was the right choice, across the board? Let me bow before your awesome omniscience! Why didn't they come to you in the first place when designing the language?

      Well done! You defeated that straw man with aplomb! Go you!

      You -speficially- mentioned the C++ runtime. I pointed out one particularly notable aspect of the runtime where they did indeed make the correct choice.

      Apparently your brain has invented the throught that this means I agree with every decision the C++ committee made about every bit of undefined behaviour ever.

      I have a suggestion for you: before laying on the sarcastic comments, you may find it useful to actually read the post you're responding to.

      It's understandable they made the choices they did back then, but the world has changed pretty significantly, and much of what we see in C++ is there for backwards compatibility, not because it's the best choice.

      Depends what you mean by "best choice". The thing is many C+ programmers (myself included) would love to chuck out the backwards compatible crap and have the nice aspects of C++ come to the front except (and this is a HUGE except) we don't really because code written in 1998 still for the most part works.

      I regularly use a library that's been in version control since 2004 (nearly 10 years) but was developed for a considerable time before that. Some of it is excellent, some of it is not pretty. Some of the old, ugly code still works perfectly however. It's arguable whether the "right choice" for C++ could ever to remove significant amounts of backwards compatibility since one of the primary advantages of C++ is stability.

      I use C++11 now daily. All my new code is written in the nice subsed that C++11 now affords. Sadly, if they had broken significant amounts of backwarsd compatibility, I'd still be stuck on C++98.

      TL;DR Keeping cruft for backwards compatibility sucks. Breaking backwards compatibility also sucks.

      --
      SJW n. One who posts facts.
  4. Sort of by EmperorOfCanada · · Score: 2

    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.

  5. Re:this kind of comment system is dead by stenvar · · Score: 4, Informative

    I don't even know why anyone would even bother with c++. If it's a good fit, just use c.

    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.

  6. Sockets by jhol13 · · Score: 4, Insightful

    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.

    1. Re:Sockets by Viol8 · · Score: 3, Informative

      We're talking about loading libraries , not inter process communication.

      But sure, instead of loading libs written in one language into another language you could just have N processes all written in different languages and communicate that way, but it would be at least an order of magnitude (probably 2) slower than directly linking in a library to your running process.

  7. Python fairs pretty well by pieleric · · Score: 2

    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:
      * 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 .h-like file
      * 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.

  8. Re:Interfacing 2 languages that are C *is* easy by PolygamousRanchKid+ · · Score: 2

    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!
  9. Re:MOST games/media apps are implemented this way. by CommanderK · · Score: 2

    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

  10. Re:this kind of comment system is dead by ustolemyname · · Score: 3, Interesting

    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
    #ifdef __cplusplus
    extern "C" {
    #endif
        typedef struct Example_t Example_class; // what I love most is that Example_t never exists ;)
        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.

  11. Re:this kind of comment system is dead by ebno-10db · · Score: 2

    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).

  12. Re:Leave windows behind please. by RabidReindeer · · Score: 2

    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.

  13. Been there, doing that by lwriemen · · Score: 2

    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.

  14. Re:this kind of comment system is dead by serviscope_minor · · Score: 2

    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.
  15. Re:Leave windows behind please. by RabidReindeer · · Score: 2

    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.

  16. Re:The real issue by Razalhague · · Score: 2

    Because some syntaxes are better at expressing some concepts while others are better at expressing other concepts.