2011-03-26 142 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