I'd like to find a way to write an API that can be accessed from any other programming language via language bindings (or some other framework). Is it possible to do this? If so, which programming language would be the most suitable for writing a "cross-language" API? My goal is to create a single set of functions that I can access from any programming language that I'm working with, so that I won't need to manually re-write the entire API in each language.
I think C or C++ would be most suitable for your purpose. You can use SWIG (Simplified Wrapper and Interface Generator) to generate language bindings from your C or C++ API.
SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. SWIG is used with different types of target languages including common scripting languages such as Perl, PHP, Python, Tcl and Ruby. The list of supported languages also includes non-scripting languages such as C#, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go language, Java including Android, Lua, Modula-3, OCAML, Octave and R. Also several interpreted and compiled Scheme implementations (Guile, MzScheme/Racket, Chicken) are supported. SWIG is most commonly used to create high-level interpreted or compiled programming environments, user interfaces, and as a tool for testing and prototyping C/C++ software. SWIG is typically used to parse C/C++ interfaces and generate the 'glue code' required for the above target languages to call into the C/C++ code. SWIG can also export its parse tree in the form of XML and Lisp s-expressions. SWIG is free software and the code that SWIG generates is compatible with both commercial and non-commercial projects...
There are pretty much 2 ways:
- a C API. Practically ever language there ever was will load a C library and call its functions. How you do this depends on the source language.
- a RPC mechanism of some sort. This can be a REST API running over HTTP, or a binary interface running over a socket. Unless you go for the lowest common denominator mechanism (eg a socket) you run the risk of not having client access routines (eg some languages do not have the right SOAP clients to call an API implemented using SOAP, or there are interoperability issues). Stick to the simplest, either a HTTP/REST interface, or a socket. Sockets have the advantage that they do not need a HTTP server to expose the interface to the clients, and can more easily run on the same server as the client with better performance.
The work required for this changes depending on the system used, for example, a socket interface will work, but client-side libraries tend to be more low-level compared to http libraries.
You could try finding a networking library that supports all the languages you want to use, and implement the API in terms of that library - eg, using ZeroMQ gives you a lot of flexibility, so you'd write your API using ZeroMQ interfaces, and then any language that wants to call your API must use the ZeroMQ client library to do so. Choose a library that supports a broad range of languages, and allows you to in-process as well as out-of-process communication for best performance.
By API, what exactly do you mean?
On many platforms you could link to a DLL or similar construction, but would having to be re-compiled for a particular native target (Intel/ARM) or endianness still qualify? A particular binary interface might still have difficulties with certain languages because of datatype issues or constructs (pointers trying to be returned to languages which don't support them well), so you would also have to consider the design of the API itself so as not to exclude some languages or make its use from those languages cumbersome.
Something portable like C and an interface based on binary endpoints in a DLL might be fine and generally callable on most platforms and from most languages, but it might need to be compiled differently and/or offered in different flavors or linked to different static libraries.
It seems to me that the choice of language you write your library or service or whatever is, by definition, not intrinsic to the question until you've given more about the platform/service the API exposes. If you can assume a network stack is available and direct-linked function-call-level performance is not a requirement, the API could easily be HTTP-based with some kind of shim for the client language to make the requests transparent.
I think in general this question is overly broad to be useful in the real world, because you haven't given indication about what kind of API might be suitable given the type of service which is being offered.
To add to above answers that suggest using an RPC mechanism. You could use Apache Thrift.(http://thrift.apache.org/). It is basically a RPC framework.
As per the Thrift wiki:
Have any language write out a text file with function to call with params to pass in. Have your "I get along with anybody" app watching a directory and once it sees a process-call.txt have it go to work. No servers or network protocols; even a non-computer language method can init the functions. Even a person could just create the text file.
Content could look like:
Call-method: fdisk() Params: (string) "/root", (string) "write-back-file-expected.txt"
;) you might wait forever to get an answer though. You just need to push a few bytes to the other process, but I'm sure that's not the whole spec.
OpenGL is a good example of what you describe - it's an API written in C, designed in a way that is easy to write bindings for in other languages
C libraries can be called from most programming languages (usually as compiled extensions, or things like PyPy's
All functions take simple data-types as arguments (boolean, integer, floating point, constants, arrays), as functions taking pointers can be awkward to translate into some languages
- Having it's own numeric data-types, which specify precision and signed'ness (whereas
floatetc can differ)
The resulting API isn't necessarily the nicest-to-use C API you could write if targeting only C users. However it means the functions can be almost directly exposed to another language (e.g the PyOpenGL docs list the differences, most of which are pretty minimal)
On top of this verbose API, you can write more "developer friendly" wrappers around this (game frameworks and such)