外部関数インターフェース(FFI )とは、あるプログラミング言語で書かれたプログラムが、別のプログラミング言語で書かれた、またはコンパイルされた相互運用可能なルーチンを呼び出したり、サービスを利用したりするための仕組みです。FFIは、バイナリダイナミックリンクライブラリへの呼び出しが行われるような場面でよく使用されます。
この用語は、 Common Lispの仕様に由来し、言語間呼び出しを可能にするプログラミング言語機能を明示的に指しています。[ 1 ]この用語は、 Haskell、[ 2 ] Rust、[ 3 ] PHP、[ 4 ] Python、およびLuaJIT ( Lua )のインタプリタおよびコンパイラのドキュメントでも公式によく使用されています。[ 5 ] [ 6 ] : 35 [ 7 ]他の言語では別の用語が使用されています。Adaには言語バインディングがあり、JavaにはJava Native Interface (JNI)、Java Native Access (JNA)、または Java 22 以降ではForeign Function and Memory API があります。Foreign Function Interface は、このようなサービスを提供するメカニズムの一般的な用語となっています。
外部関数インターフェースの主な機能は、一方のプログラミング言語(ホスト言語、つまりFFIを定義する言語)のセマンティクスと呼び出し規約を、もう一方のプログラミング言語(ゲスト言語)のセマンティクスと規約に適合させることです。このプロセスでは、両方の実行環境とアプリケーションバイナリインターフェースも考慮する必要があります。これにはいくつかの方法があります。
C++ は C との互換性を簡単に提供しますが、C++ は名前マングリングを使用するため、共有ライブラリでエクスポートされるシンボルは、名前マングリングを防止するextern "C"ブロックでラップする必要があります。関数は内部で C++ コードを呼び出すことができますが、C 型のみを返すことができ、例外extern "C"をスローすることはできません。
FFIsは、以下の点を考慮すると複雑になる可能性があります。

多くの FFI は自動的に生成できます。たとえばSWIG などです。ただし、拡張言語の場合、ゲストとホストの関係の意味的な反転が発生する可能性があります。たとえば、より小さな拡張言語が、より大きなホスト言語のサービスを呼び出すゲストである場合です。たとえば、GIMP 用の小さなプラグイン[ 8 ]を作成する場合などです。[ 9 ]
一部のFFIは独立した関数に限定されていますが、オブジェクトやクラスに埋め込まれた関数(メソッド呼び出しと呼ばれることが多い)の呼び出しも許可するものもあり、中には複雑なデータ型やオブジェクトを言語境界を越えて移行できるものもあります。
ほとんどの場合、FFIは上位言語で定義されるため、下位言語(通常はCやC++などのシステムプログラミング言語)で定義および実装されたサービスを利用できます。これは通常、オペレーティングシステム(OS)APIが定義されている言語でOSサービスにアクセスするため、またはパフォーマンス向上を目的として行われます。
多くのFFIは、呼び出される言語がホスト言語でサービスを呼び出すための手段も提供しています。
外部関数インターフェースという用語は、一般的に、Microsoft Common Language Runtimeのような多言語ランタイムを説明するために使用されません。このようなランタイムでは、共通の基盤が提供され、CLR に準拠する言語であれば、他の言語で定義されたサービスを使用できるようになります。(ただし、この場合、CLR にはランタイム外部を呼び出すための FFI であるP/Invokeが含まれています。)さらに、Java リモート メソッド呼び出し(RMI)、RPC、CORBA、SOAP、D-Busなどの多くの分散コンピューティング アーキテクチャでは、異なるサービスを異なる言語で記述できますが、このようなアーキテクチャは一般的に FFI とはみなされません。
ClojureとJava、ElixirとErlangのように、言語が同じバイトコードVMにコンパイルされる特殊なケースもいくつかあります。インターフェースが存在しないため、厳密にはFFIではありませんが、ユーザーには同じ機能を提供します。
Haskell の FFI は、他の言語 (基本的には C ) の関数を呼び出すため、および C 言語から Haskell の関数を呼び出すために使用されます。
このモジュールは、他のプログラミング言語や基盤となるオペレーティングシステムなど、Rust以外のインターフェースを介してデータを処理するためのユーティリティを提供します。主にFFI(外部関数インターフェース)バインディングや、Cライクな文字列を他の言語と交換する必要のあるコードに役立ちます。
定義された C 変数は、FFI インスタンスのプロパティとして利用可能になります。
用の C 外部関数インターフェース。目的は、C で記述されたインターフェース宣言を使用して、コンパイル済みの C コードを Python から呼び出すための便利で信頼性の高い方法を提供することです。