外部関数インターフェース

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ

外部関数インタフェースFFIは)1つので書かれたプログラムするメカニズムであるプログラミング言語は、ルーチンを呼び出すか、別で書かれたサービスを利用することができます。

ネーミング

この用語は、Common Lispの仕様に由来します。これは、言語間呼び出しの言語機能自体を明示的に指します。[1]この用語は、Haskell[2] Rust[3]およびPythonプログラミング言語でも公式に使用されています。[4] 他の言語は他の用語を使用します。Adaプログラミング言語は「言語バインディングについて話しますがJavaはそのFFIをJNI(Java Native Interface)またはJNA(Java Native Access)と呼びます。)。外部機能インターフェースは、そのようなサービスを提供するメカニズムの一般的な用語になっています。

操作

外部関数インターフェースの主な機能は、あるプログラミング言語(ホスト言語、またはFFIを定義する言語)のセマンティクスと呼び出し規約を、別のプログラミング言語(ゲスト言語)のセマンティクスと規約と結合することです。このプロセスでは、両方ランタイム環境アプリケーションバイナリインターフェイスも考慮する必要がありますこれはいくつかの方法で行うことができます。

  • ホスト言語で呼び出し可能となるゲスト言語関数を特定の方法で指定または実装する必要があります。多くの場合、何らかの互換性ライブラリを使用します。
  • ツールを使用して、ゲスト言語関数を適切なグルーコード自動的に「ラップ」し、必要な翻訳を実行します。
  • ラッパーライブラリの使用
  • 言語間で使用できるホスト言語機能のセットを制限します。たとえば、Cから呼び出されたC ++関数は、(一般に)参照パラメーターを含めたり、例外をスローしたりすることはできません。

FFIは、次の考慮事項によって複雑になる可能性があります。

  • 一方の言語がガベージコレクション(GC)をサポートし、もう一方の言語がサポートしていない場合。非GC言語コードは、他の言語のGCを失敗させるものではないことに注意する必要があります。たとえば、JNIでは、Javaから受信するオブジェクト参照を「保持」するCコードは、この事実をJavaランタイム環境(JRE)に「登録」する必要があります。そうしないと、JavaはCがオブジェクトを処理し終える前にオブジェクトを削除する可能性があります。(Cコードは、Cがそのオブジェクトをそれ以上必要としなくなったら、そのようなオブジェクトへのリンクを明示的に解放する必要もあります。)
  • 複雑または重要なオブジェクトまたはデータ型は、ある環境から別の環境にマッピングするのが難しい場合があります。
  • 上記のマッピングの問題により、両方の言語が可変オブジェクトの同じインスタンスへの参照を維持できない場合があります。
  • 一方または両方の言語が仮想マシン(VM)で実行されている可能性がありますさらに、両方がそうである場合、これらはおそらく異なるVMになります。
  • 型システム間やオブジェクト構成モデルなど、言語間の継承やその他の違いは特に難しい場合があります。

言語別

FFIの例は次のとおりです。

  • Ada言語バインディング。外部関数を呼び出すだけでなく、その関数とメソッドをエクスポートして、Ada以外のコードから呼び出すこともできます。[5]
  • C ++はとの些細なFFI持つCの言語は重要な共通のサブセットを共有するように、。C ++でのextern "C"宣言の主な効果は、C ++の名前マングリングを無効にすることです。
  • Cleanは、Cまたはstdcall呼び出し規約に従ってすべての言語で双方向FFIを提供します[6] [7]
  • CNI、GNUコンパイラ環境で使用されるJNIの代替。
  • Dは、C ++と同じ方法で、extern "C"からextern(C ++)を使用します。
  • Dartに、モバイル、コマンドライン、およびサーバーアプリケーション用のネイティブCコードを呼び出すためのdart:ffi [8]ライブラリが含まれています
  • PythonPerlTclRubyなどの動的言語すべて、C / C ++(またはC / C ++の呼び出し規則に従った他の言語)で記述されたネイティブコードに簡単にアクセスできます。
  • Factorには、C、FortranObjective-C、およびWindowsCOM用のFFIがありますこれらはすべて、任意の共有ライブラリを動的にインポートおよび呼び出すことができます。
  • FFIsのCommon LispHaskellの
  • Fortran 2003には、相互運用可能なデータ型(組み込み型とPOD構造体の両方)、相互運用可能なポインター、相互運用可能なグローバルデータストア、およびFortranからCを呼び出し、CからFortranを呼び出すメカニズムを提供するモジュールISO_C_BINDINGがあります。[9]
  • Goは、"C"疑似パッケージを介してCコードを直接呼び出すことができます。[10]
  • JavaがJavaScriptにコンパイルされているGWTには、JSNIと呼ばれるFFIがあり、Javaソースが任意のJavaScript関数を呼び出したり、JavaScriptがJavaにコールバックしたりできるようにします。
  • JNIはJavaとC / C ++の間のインターフェースを提供します。これは、Javaがデプロイされているほとんどのシステムで推奨されるシステム言語です。JNAは、グルーコードを記述せずにネイティブライブラリとのインターフェイスを提供します別の例はJNRです
  • NimにはFFIがあり、CC ++Objective-Cのソースを使用できますまた、Javascriptとのインターフェースも可能です。
  • Juliaには、ccallC(およびFortranなどの他の言語)を呼び出すためのキーワードがあります。[11]同様のボイラープレートなしのサポートを提供するパッケージは、Python [12](OOサポートやGCサポートなど)、Java(Scalaなどの他のJDK言語をサポート)、Rなどの一部の言語で利用できます。.C ++でのインタラクティブな使用は、Cxx.jlパッケージでも可能です。
  • PHPはCにFFIを提供します。[13]
  • Rubyは、ffigemまたは標準ライブラリfiddleのいずれかを介してFFIを提供します
 「フィドル」が必要

libm  = フィドルdlopen '/ lib / libm.so.6' 

#同等:double floor(double x); 
フロア = フィドル::関数新しい
  のlibm SYM 「フロア」)、      のPTRは、フィドル::ハンドルの参照関数(またはシンボル)である。
  [フィドル:: TYPE_DOUBLEは]  #引数PTR関数に渡される引数の配列、です。
  フィドル:: TYPE_DOUBLE     #ret_typeは関数の戻り型です


#同等:floor(3.14159); 
コール3 14159  #=> 3.0
  • Pythonctypescffiモジュールを提供します。たとえば、ctypesモジュールは、共有ライブラリ/ DLLからオンザフライでC関数をロードし、次のようにPythonとCのセマンティクス間で単純なデータ型を自動的に変換できます。
     ctypes 
    libc  =  ctypesをインポートします。CDLL ' / lib / libc.so.6'   #Linux / Unix 
    t  =  libcの場合time なし                   #同等のCコード:t = time(NULL)
    print t 
    
  • P / Invokeは、Microsoft共通言語ランタイムとネイティブコード間のインターフェイスを提供します
  • Racketには、マクロに大きく基づいたネイティブFFIがあり、任意の共有ライブラリを動的にインポートできます。[14] [15]
  • Rakuは、RubyPythonPerlBrainfuckLuaCC ++Go、Scheme Guile / Gambitを呼び出すことができます[16] [17]
  • Rustは、外部関数インターフェースも定義します。[18]
  • Visual Basicには、Unicode以外のC関数を呼び出すことができる宣言型の構文があります。
  • コンポーネントオブジェクトモデルのベースの1つは、文字列と配列にVisualBasicと同じタイプをネイティブに使用する一般的なインターフェイス形式です。
  • Luaのジャストインタイム実装であるLuaJITには、「外部C関数の呼び出しと純粋なLuaコードからのCデータ構造の使用」を可能にするFFIがあります。[19]
  • PhoneGap以前はApache Callbackという名前で呼ばれていましたが、現在はApache Cordova)は、HTML、CSS、およびJavaScriptを使用してネイティブモバイルアプリケーションを構築するためのプラットフォームです。さらに、Accelerometer、Camera(PhotoLibraryとSavedPhotoAlbumも)、Compass、Storage(SQLデータベースとlocalStorage)、Notification、Media、Capture(再生と録音またはオーディオ)などの携帯電話のネイティブ機能のメソッドとプロパティにアクセスするためのJavaScriptコールバック関数を介したFFIがありますおよびビデオ)、ファイル、連絡先(アドレス帳)、イベント、デバイスおよび接続情報。[1][2]
  • Wolfram言語はWSTP(Wolfram Symbolic Transfer Protocol)と呼ばれる技術を提供し、C ++、Java、.NETおよび他の言語のバインディングを使用して他の言語間でコードを双方向に呼び出すことを可能にします。
  • Zigは、組み込みcImport関数を使用してcにFFIを提供します。[20]

さらに、多くのFFIを自動的に生成できます(たとえば、SWIG)ただし、拡張言語の場合、小さなプラグインを作成するなど、拡張言語の小さな本体がホスト言語の大きな本体でサービスを呼び出すゲストである場合、ゲストとホストの関係のセマンティック反転が発生する可能性があります[21 ] GIMPの場合。[22]

一部のFFIは独立した関数に制限されていますが、他のFFIは、オブジェクトまたはクラスに埋め込まれた関数の呼び出し(メソッド呼び出しと呼ばれることもありますも許可します言語の境界を越えて複雑なデータ型やオブジェクトを移行できるものもあります。

ほとんどの場合、FFIは「高水準」言語で定義されているため、低水準言語(通常はCC ++などのシステム言語)で定義および実装されたサービスを使用できますこれは通常、OSのAPIが定義されている言語でOSサービスにアクセスするため、またはパフォーマンスを考慮して行われます。

多くのFFIは、呼び出された言語がホスト言語でサービスを呼び出すための手段も提供します。

外部関数インターフェイスという用語は、通常、Microsoft Common Language Runtimeなどの多言語ランタイムを表すために使用されません。MicrosoftCommonLanguageRuntimeでは、CLR準拠の言語が他の言語で定義されたサービスを使用できるようにする共通の「サブストレート」が提供されます。(ただし、この場合、CLRには、ランタイムの外部で呼び出すためのFFI、P / Invokeが含まれています。)さらに、Java Remote Method Invocation(RMI)、RPC、CORBASOAPD-などの多くの分散コンピューティングアーキテクチャバスでは、さまざまなサービスをさまざまな言語で作成できます。このようなアーキテクチャは、通常、FFIとは見なされません。

特別な場合

ClojureJavaElixirErlangなど、言語が同じバイトコードVMにコンパイルされる特殊なケースがいくつかありますインターフェイスがないため、厳密に言えばFFIではありませんが、ユーザーに同じ機能を提供します。

も参照してください

参考文献

  1. ^ 「CFFIユーザーマニュアル」common-lisp.org 2015年618取得
  2. ^ 「FFIの紹介」HaskellWiki 検索された19年6月2015年HaskellのFFIは、他の言語(この時点では基本的にC)から関数を呼び出すために使用され、CがHaskell関数を呼び出すために使用されます。
  3. ^ "std :: ffi-Rust" 2021年4月1日取得このモジュールは、他のプログラミング言語や基盤となるオペレーティングシステムなど、Rust以外のインターフェイス間でデータを処理するためのユーティリティを提供します。これは主に、Cのような文字列を他の言語と交換する必要があるFFI(Foreign Function Interface)バインディングおよびコードに使用されます。
  4. ^ 「CFFIドキュメント」検索された19年6月2015年CPythonの外部関数インターフェイス。目標は、Cで記述されたインターフェイス宣言を使用して、PythonからコンパイルされたCコードを呼び出すための便利で信頼性の高い方法を提供することです。
  5. ^ 「他の言語へのインターフェース」Adaic.org 2013年9月29日取得
  6. ^ 「外国の輸出」2020525日取得
  7. ^ 「クリーンからCを呼び出す」2018425日取得
  8. ^ 「dart:ffiライブラリ」2020年1月1取得
  9. ^ " ' fortran-iso-c-binding 'タグウィキ"スタックオーバーフロー
  10. ^ 「cgo—Goプログラミング言語」取得した2015年8月23日を
  11. ^ 「CおよびFortranコードの呼び出し・Julia言語」docs.julialang.org 2018年2月11日取得
  12. ^ PyCall.jl:パッケージはジュリア言語からPython関数を呼び出すため、JuliaPy、2018年2月8日には、取得した2018年2月11日を
  13. ^ 「PHP:FFI-マニュアル」PHPグループ2019年6月13日取得
  14. ^ EliBarzilay。「ラケット外部インターフェース」Docs.racket-lang.org 2013年9月29日取得
  15. ^ 「TR600.pdf」(PDF)2013年9月29日取得
  16. ^ 「インライン実装」2017815日取得
  17. ^ 「ネイティブコール」2017815日取得
  18. ^ 「extern関数を使用した外部コードの呼び出し」20196月1取得
  19. ^ マイクポール。「FFIライブラリ」Luajit.org 2013年9月29日取得
  20. ^ 「Cヘッダーファイルからインポート」Zig SoftwareFoundation 2021-03-11を取得
  21. ^ 「4。サンプルスクリプト」Gimp.org。2001-02-04 2013年9月29日取得
  22. ^ 「GIMP用のScript-Fuとプラグイン」Gimp.org 2013年9月29日取得

外部リンク