40

異なるプログラミング言語を混在させることは、長い間私にはよく理解できませんでした。このウィキペディアの記事によると、外部関数インターフェイス (または FFI) はいくつかの方法で実行できます。

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

私の質問:

  1. 1番目、2番目、3番目の方法の違いは何ですか? それらはすべて、呼び出された言語のコードをオブジェクトファイルとヘッダーファイルを含むライブラリにコンパイルし、呼び出し言語によって呼び出されるように思えます。

  2. リンクされているあるソースによると、FFI の実装はいくつかの方法で行うことができます。

    • ターゲット言語で呼び出された関数が特定のプロトコルを実装することを要求します。
    • 特定の低言語関数を受け取り、それをコードで「ラップ」して、高レベル言語規則との間でデータ変換を行うラッパー ライブラリを実装します。
    • 高レベル機能のサブセット (低レベル言語と互換性がある) を使用するために、ネイティブとして宣言された関数を要求する。

    リンクされたソースの最初の方法がウィキペディアの最初の方法と同じかどうか疑問に思っていましたか?

    このソースの 3 番目の方法はどういう意味ですか? ウィキペディアの4番目の方法に対応していますか?

  3. 同じソースで、リストされている 3 つの方法を比較すると、2 つの言語の間のギャップを埋める仕事が、呼び出された言語から呼び出した言語に徐々に移行していると言えます。私はそれをどのように理解するのだろうかと思っていました。この変化は、ウィキペディアの 4 つの方法にも当てはまりますか?

  4. 言語バインディングと FFI は同等の概念ですか? それらはどのように関連し、異なるのでしょうか?

    プログラミング言語からライブラリまたは OS サービスへのバインディングは、言語でそのサービスを提供する API です。

  5. ウィキペディアまたはソースからの引用で、次の各例がどの方法に属しているのか疑問に思っていましたか?

4

1 に答える 1

23

具体的な例が役立つかもしれません。ホスト言語を Python、ゲスト言語を C とします。これは、Python が C 関数を呼び出すことを意味します。

  1. 最初のオプションは、特定の方法で C ライブラリを作成することです。Py_Object *Python の場合、標準的な方法は、他の条件の中で最初のパラメーターを使用して C 関数を作成することです。例(ここから):

    static PyObject *
    spam_system(PyObject *self, PyObject *args)
    {
        const char *command;
        int sts;
    
        if (!PyArg_ParseTuple(args, "s", &command))
            return NULL;
        sts = system(command);
        return Py_BuildValue("i", sts);
    }
    

    Python から呼び出し可能な C 関数です。これが機能するには、Python との互換性を念頭に置いてライブラリを作成する必要があります。

  2. 既存の C ライブラリを使用する場合は、別のオプションが必要です。1 つは、この既存のライブラリをホスト言語で使用するのに適した形式でラップするツールを用意することです。多くの言語を結びつけるために使用できるSwigを見てみましょう。既存の C ライブラリがあれば、swig を使用して、Python の規則に準拠しながら既存のライブラリを呼び出す C コードを効果的に生成できます。Python モジュールのビルドの例を参照してください。

  3. 既存の C ライブラリに対するもう 1 つのオプションは、ctypesのように、実行時に呼び出しを効果的にラップする Python ライブラリから呼び出すことです。オプション 2 ではコンパイルが必要でしたが、今回は必要ありません。

もう 1 つのことは、ある言語の関数を別の言語から呼び出すための多くのオプション (重複する) があることです。通常、同じプロセス内の複数の言語間での呼び出しを参照するFFI(私が知る限り、言語バインディングと同等)があり(いわば同じ実行可能ファイルの一部として)、プロセス間通信手段(ローカルおよびネットワーク)があります。 . 一般に、CORBA や Web サービス (SOAP または REST)、COM+ やリモート プロシージャ コールなどは 2 番目のカテゴリに属し、FFI とは見なされません。実際、彼らはほとんどの場合、コミュニケーションの両側で使用される特定の言語を規定していません. CORBA や SOAP などのネットワーク ベースの APi の場合は簡略化されていますが、大まかに IPC (プロセス間通信) オプションと呼んでいます。

あなたのリストを見て、私は次の意見を思いつきます:

  • Common Object Request Broker アーキテクチャ: FFI ではなく IPC
  • extern "C"名前マングリングを無効にするための C++ での宣言によって、C++ で C を呼び出します。****
  • 共有ライブラリへの MATLAB インターフェイスオプション 3 (ctypes のような)による、Matlab での C の呼び出し
  • C/C++ 言語 MEX ファイルの作成による Matlab での C の呼び出しオプション 2 (swig のようなもの)
  • mcc コンパイラオプション 2 による C での Matlab の呼び出し (swig のようなもの)
  • JNI による Java での C++ の呼び出し、および JNIオプション 3 による C++ での Java の呼び出し (ctypes のようなもの)
  • SWIGオプション 2 (swig)を使用して、他の言語で C/C++ を呼び出す
  • Ctypesオプション 3 (ctypes)による Python での C の呼び出し
  • Cythonオプション 2 (swig のような)
  • 一部はRPyオプション3(ctypesのような)で、一部はデータ交換について(FFIではない) 、PythonでRを呼び出す

次の 2 つは、用語が使用されているため、まったく外部関数インターフェイスではありません。FFi は、プログラミング言語間の相互作用に関するものであり、(適切な制限付きで) ある言語の任意のライブラリを他の言語で使用できるようにすることができる必要があります。1 つの言語からアクセスできる特定のライブラリは、FFI を作成しません。

  • さまざまな言語から OpenGL へのプログラミング言語バインディング
  • さまざまな言語の C ライブラリのバインディング
于 2011-03-30T16:26:39.737 に答える