2011-03-26 34 views
15

混合不同的編程語言一直以來我都不太明白。據this Wikipedia article,外國功能接口(或FFI)可以通過多種方式來完成:瞭解外部函數接口(FFI)和語言綁定

  1. 要求客人語言功能,這些功能是宿主語言調用指定或以一種特殊的方式來實現;經常使用某種兼容性庫。
  2. 使用工具自動「包裝」客人語言功能與適當的膠水代碼,執行任何必要的翻譯。
  3. 包裝庫的使用
  4. 限制可以跨語言使用的一組主機語言功能。例如,從C調用的C++函數可能(通常)不包括引用參數或拋出異常。

我的問題:

  1. 什麼 第1,第2和第3的方式之間的區別是什麼?看來 我都是把 的代碼編譯成 這個庫的目標文件和頭文件 ,然後調用語言爲 。
  2. One source it links說, 實現一個FFI可以 幾種方式來完成:

    • 需要在目標語言調用的函數實現 特定的協議。
    • 實現一個包含給定的低語言函數的包裝庫,並用代碼「包裝」它以執行與高級語言約定的數據轉換或從 高級語言約定中進行數據轉換。
    • 需要本地聲明使用高級功能子集(與低級語言兼容)的函數。

    我在想,如果在 聯動源的第一種方式是相同維基百科 第一種方式?

    這個 源代表的第三種方式是什麼意思?它對應於維基百科中的第四種方式嗎?

  3. the same source,比較三種方式它列出的時候,似乎想說 填充 兩種語言之間的差距的工作是逐步 從所謂的語言 給調用語言轉向。我是 想知道如何理解?這種轉變在維基百科的四種方式中也是如此嗎?
  4. Language binding和FFI 等效概念?他們如何 相關和不同?

    從一種編程語言 庫或OS服務綁定在 語言提供服務的API 。

  5. 我想知道在維基百科或源代碼的引用中哪個方法屬於哪個屬性?

感謝您的啓示!最好的問候!

回答

13

可能是一個具體的例子將有所幫助。讓我們將主機語言作爲Python,將客體語言作爲C.這意味着Python將調用C函數。

  1. 第一種選擇是以特定方式編寫C庫。在Python的情況下,標準的方法是在其他條件下使用Py_Object *的第一個參數編寫C函數。例如(from here):

    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庫,則需要其他選項。一種是有一種工具可以生成適合宿主語言使用的格式的現有庫。拿Swig可以用來綁定多種語言。給定一個現有的C庫,您可以使用swig來有效生成C代碼,該代碼可以調用現有的庫,同時符合Python約定。有關構建Python模塊,請參閱the example

  3. 我們已經存在的C庫的另一種選擇是從運行時有效包裝調用的Python庫調用它,如ctypes。雖然在選項2編譯是必要的,但現在不是這樣。

另一件事是有很多選項(它們重疊)用於從另一種語言調用一種語言的函數。有FFI(據我所知,語言綁定相當於),通常是指在相同的過程(作爲同一個可執行文件的一部分,可以這麼說)在多種語言之間調用,並且存在進程間通信手段(本地和網絡)。像CORBA和Web服務(SOAP或REST)和COM +和遠程過程調用一般屬於第二類,並不被視爲FFI。事實上,他們大多不會在交流的任何一方規定任何特定的語言。我會鬆散地將它們作爲IPC(進程間通信)選項,儘管這對於基於網絡的APi(如CORBA和SOAP)來說是簡化的。

有你的列表中去,我冒昧提出如下意見:

  • 公共對象請求代理體系結構:IPC,不FFI
  • 在調用C++ C,通過在C extern "C"聲明++禁用名稱修改。 ****
  • 調用C在Matlab,通過MATLAB接口共享庫選項3(ctypes的樣)
  • 調用在Matlab C,通過創建C/C++語言MEX-文件選項2(swig-等)
  • 調用Matlab在C,通過MCC編譯選項2(大口狀)
  • 調用C++在Java中,通過JNI,以及中調用Java在C++通過JNI 選項3(ctypes的樣)
  • 在其他語言中調用C/C++ S,使用SWIG 選項2(大口)在Python
  • 調用C,通過ctypes的選項3(ctypes的)
  • 用Cython 選項2(痛飲樣)在Python
  • 調用R,由RPY 選項3(ctypes的樣)部分,另一部分關於數據交換(不FFI)

接下來的兩個是不是在所有的外國功能接口,作爲長期使用。 FFi是關於編程語言之間的交互,應該能夠從一種語言向另一種語言提供任何庫(具有適當的限制)。從一種語言訪問的特定圖書館不是FFI製作的。

  • 程序語言的結合,以各種語言
  • 綁定C庫OpenGL的各種語言
+0

+1很好的答案。一個註釋:「通過創建MEX文件在MATLAB中調用C」更像是「選項1」,它相當於使用C API編寫Python擴展。您使用接收'mxArray *'參數的特殊網關例程創建常規共享庫。至於「使用mcc編譯器在C中調用MATLAB」,它並不是真正的FFI,因爲這只是調用其他C代碼(MCC編譯器生成常規共享庫)的C代碼。 – Amro 2013-06-25 09:21:40

+0

未提及的另一個選擇是「使用MATLAB引擎在C中調用MATLAB」,它類似於[「Python嵌入」](http://docs.python.org/2/extending/embedding.html)繼續類比(和使用JNI接口在C中調用Java一樣) – Amro 2013-06-25 09:23:47