The Challenge of Cross-Language Interoperability 286
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."
Re:Cross language - what .Net gets right (Score:3, 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.
Re:this kind of comment system is dead (Score:4, 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 // 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 [dabeaz.com].