This article's use of external links may not follow Wikipedia's policies or guidelines. Please improve this article by removing excessive or inappropriate external links, and converting useful links where appropriate into footnote references. (August 2016) (Learn how and when to remove this template message)

A foreign function interface (FFI) is a mechanism by which a program written in one programming language can call routines or make use of services written in another.

Naming

The term comes from the specification for Common Lisp, which explicitly refers to the language features for inter-language calls as such;[1] the term is also used officially by the Haskell,[2] Rust,[3] and Python programming languages.[4] Other languages use other terminology: the Ada programming language talks about "language bindings", while Java refers to its FFI as the JNI (Java Native Interface) or JNA (Java Native Access). Foreign function interface has become generic terminology for mechanisms which provide such services.

Operation

The primary function of a foreign function interface is to mate the semantics and calling conventions of one programming language (the host language, or the language which defines the FFI), with the semantics and conventions of another (the guest language). This process must also take into consideration the runtime environments and/or application binary interfaces of both. This can be done in several ways:

FFIs may be complicated by the following considerations:

By language

Examples of FFIs include:

require 'fiddle'

libm = Fiddle.dlopen('/lib/libm.so.6')

# Equivalent to: double floor(double x);
floor = Fiddle::Function.new(
  libm.sym('floor'),     # ptr is a referenced function(, or symbol), of a Fiddle::Handle.
  [Fiddle::TYPE_DOUBLE], # args is an Array of arguments, passed to the ptr function.
  Fiddle::TYPE_DOUBLE    # ret_type is the return type of the function
)

# Equivalent to: floor(3.14159);
floor.call(3.14159) #=> 3.0

In addition, many FFIs can be generated automatically: for example, SWIG. However, in the case of an extension language a semantic inversion of the relationship of guest and host can occur, when a smaller body of extension language is the guest invoking services in the larger body of host language, such as writing a small plugin[21] for GIMP.[22]

Some FFIs are restricted to free standing functions, while others also allow calls of functions embedded in an object or class (often called method calls); some even permit migration of complex datatypes and/or objects across the language boundary.

In most cases, an FFI is defined by a "higher-level" language, so that it may employ services defined and implemented in a lower level language, typically a systems language like C or C++. This is typically done to either access OS services in the language in which the OS' API is defined, or for performance considerations.

Many FFIs also provide the means for the called language to invoke services in the host language as well.

The term foreign function interface is generally not used to describe multi-lingual runtimes such as the Microsoft Common Language Runtime, where a common "substrate" is provided which enables any CLR-compliant language to use services defined in any other. (However, in this case the CLR does include an FFI, P/Invoke, to call outside the runtime.) In addition, many distributed computing architectures such as the Java remote method invocation (RMI), RPC, CORBA, SOAP and D-Bus permit different services to be written in different languages; such architectures are generally not considered FFIs.

Special cases

There are some special cases, in which the languages compile into the same bytecode VM, like Clojure and Java, as well as Elixir and Erlang. Since there is no interface, it is not an FFI, strictly speaking, while it offers the same functionality to the user.

See also

References

  1. ^ "CFFI User Manual". common-lisp.org. Retrieved 2015-06-18.
  2. ^ "FFI Introduction". HaskellWiki. Retrieved 19 June 2015. Haskell's FFI is used to call functions from other languages (basically C at this point), and for C to call Haskell functions.
  3. ^ "std::ffi - Rust". Retrieved 1 April 2021. This module provides utilities to handle data across non-Rust interfaces, like other programming languages and the underlying operating system. It is mainly of use for FFI (Foreign Function Interface) bindings and code that needs to exchange C-like strings with other languages.
  4. ^ "CFFI documentation". Retrieved 19 June 2015. C Foreign Function Interface for Python. The goal is to provide a convenient and reliable way to call compiled C code from Python using interface declarations written in C.
  5. ^ "Interface to Other Languages". Adaic.org. Retrieved 2013-09-29.
  6. ^ "Foreign Export". Retrieved 2020-05-25.
  7. ^ "Calling C From Clean". Retrieved 2018-04-25.
  8. ^ "dart:ffi library". Retrieved 2020-01-01.
  9. ^ "'fortran-iso-c-binding' tag wiki". Stack Overflow.
  10. ^ "cgo — The Go Programming Language". Retrieved 2015-08-23.
  11. ^ "Calling C and Fortran Code · The Julia Language". docs.julialang.org. Retrieved 2018-02-11.
  12. ^ PyCall.jl: Package to call Python functions from the Julia language, JuliaPy, 2018-02-08, retrieved 2018-02-11
  13. ^ "PHP: FFI - Manual". The PHP Group. Retrieved 13 June 2019.
  14. ^ Eli Barzilay. "The Racket Foreign Interface". Docs.racket-lang.org. Retrieved 2013-09-29.
  15. ^ "TR600.pdf" (PDF). Retrieved 2013-09-29.
  16. ^ "Inline implementations". Retrieved 2017-08-15.
  17. ^ "Native Call". Retrieved 2017-08-15.
  18. ^ "Using extern Functions to Call External Code". Retrieved 2019-06-01.
  19. ^ Mike Pall. "FFI Library". Luajit.org. Retrieved 2013-09-29.
  20. ^ "Import from C Header File". Zig Software Foundation. Retrieved 2021-03-11.
  21. ^ "4. A sample script". Gimp.org. 2001-02-04. Retrieved 2013-09-29.
  22. ^ "Script-Fu and plug-ins for The GIMP". Gimp.org. Retrieved 2013-09-29.