ForeignFunctionInterface

Last edit November 9, 2014
A ForeignFunctionInterface (FFI) is an interface that allows calling code written in one programming language, from another that is neither a superset nor a subset.

The term comes from CommonLisp; though it's applicable to any such interface. Other language communities don't use the term FFI as much; some languages such as Java have their own term -- Java refers to it as the JavaNativeInterface.

The most common cases are interfaces that allow calling CeeLanguage or CeePlusPlus from a higher-level language.

...with the caveat that the collection of functions that are callable in CeePlusPlus is restricted -- generally things that are callable from C.

There are implementations for many languages to call CeeLanguage and CeePlusPlus in SimplifiedWrapperAndInterfaceGenerator (SWIG).

Implementing an FFI can be done in several ways:

  • Requiring the called functions in the target language implement a specific protocol. JNI works in this fashion; any C/C++ function called by JNI must be defined in terms of a specific set of Java-compatible datatypes. Converting this stuff to standard C datatypes and back is (or at least was) the responsibility of the called native code. JNI also provides ways for C code to call back Java code -- necessary in many cases, especially if the C code needs to "hold on to" Java objects. The Java GarbageCollector does not examine the native code for references, so C code that holds on to Java objects must explicitly mark them reserved/unreserved (this is not necessary for objects which are arguments to native functions, but whose native functions go out of scope when the function returns).

  • Implementing a wrapper library that takes a given low-language function, and "wraps" it with code to do data conversion to/from the high-level language conventions.
  • Requiring functions declared native to use a subset of high-level functionality (which is compatible with the low-level language).

See also "Design Issues for Foreign Function Interfaces", at If we refer to the low-level language as the "host" language and the high-level language as the "guest" language, then these three approaches boil down to ways to bridge the gap between them, as follows.

  • The host is expected to bridge the gap. You have to write host-language functions specifically to be called from the guest. An API may be offered for the host language to use to communicate with guests.
  • The gap is bridged by some kind of tool that does not belong strictly to either the host or guest languages.
  • The guest is expected to bridge the gap. This means the guest language can call any host-language function, but the guest language now has to have support for many low-level features, in order to communicate with the host language effectively.

It seems that many VbClassic programs use "components" written in C.