了解外部函数接口(FFI)和语言绑定

时间:2011-03-26 07:26:05

标签: language-agnostic programming-languages binding ffi

混合使用不同的编程语言一直是我不太了解的事情。根据{{​​3}},外部函数接口(或FFI)可以通过多种方式完成:

  
      
  1. 要求以特定方式指定或实现要作为主机语言可调用的客户语言函数;经常使用某种兼容性库。
  2.   
  3. 使用工具通过适当的粘合代码自动“包装”客户语言函数,该代码执行任何必要的翻译。
  4.   
  5. 使用包装器库
  6.   
  7. 限制可以跨语言使用的主机语言功能集。例如,从C调用的C ++函数可能(通常)不包含引用参数或抛出异常。
  8.   

我的问题:

  1. 之间有什么区别 第一,第二和第三种方式?好像 我他们都要编译代码 被称为语言的一些 带有目标文件和标题的库 文件,然后被调用 呼唤语言。
  2. this Wikipedia article说, 实施FFI可以在 几种方式:

      
        
    • 要求目标语言中的被调用函数实现a   特定协议。
    •   
    • 实现一个采用给定低语言的包装器库   函数,并用代码“包装”它来进行数据转换   高级语言惯例。
    •   
    • 要求声明为native的函数使用高级功能的子集(与低级语言兼容)。
    •   

    我想知道是否第一种方式 链接的源与 维基百科的第一种方式?

    第三种方式是什么? 来源意思?它是否符合维基百科的第四种方式?

  3. One source it links中,当比较它列出的三种方式时,似乎可以说 弥补差距的工作 这两种语言正逐渐形成 从被叫语言转移 到调用语言。我曾是 想知道怎么理解?对于维基百科中的四种方式,这种转变也是如此吗?
  4. the same source和FFI 等同的概念?他们怎么样 相关和不同?

      

    来自编程语言的绑定   库或OS服务是API   提供该服务   语言。

  5. 我想知道维基百科的引文中的哪一种方式或以下每个例子所属的来源?

  6. 感谢您的启发!最好的问候!

1 个答案:

答案 0 :(得分:14)

可能是一个具体的例子会有所帮助。让我们将宿主语言作为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中编译是必要的,但现在还不是。

  4. 另一件事是,有很多选项(重叠)用于从另一种语言调用一种语言的函数。有FFI(相当于我所知的语言绑定),它通常指的是在同一进程中的多个语言之间调用(作为同一个可执行文件的一部分,可以这么说),并且有进程间通信手段(本地和网络)。像CORBA和Web服务(SOAP或REST)以及COM +和远程过程调用这样的东西通常属于第二类,并且不被视为FFI。实际上,他们大多没有规定在通信的任何一方使用任何特定的语言。我会松散地将它们作为IPC(进程间通信)选项,尽管这是基于网络的APi(如CORBA和SOAP)的简化。

    列出你的名单,我会冒险提出以下意见:

    • 公共对象请求代理体系结构: IPC,而不是FFI
    • 在C ++中调用C,通过C ++中的extern "C"声明来禁用名称修改。 ****
    • 在Matlab中调用C,通过MATLAB接口访问共享库选项3(类似ctypes)
    • 通过创建C / C ++语言MEX文件在Matlab中调用C 选项2(类似swig)
    • 使用mcc编译器在C中调用Matlab 选项2(类似swig)
    • 使用JNI在Java中调用C ++,在JNI中使用C ++调用Java 选项3(类似ctypes)
    • 使用其他语言调用C / C ++,使用SWIG 选项2(swig)
    • 通过Ctypes在Python中调用C 选项3(ctypes)
    • Cython 选项2(swig-like)
    • 在Python中调用R,由RPy 选项3(类似ctypes)部分,部分关于数据交换(不是FFI)

    接下来的两个根本不是外部函数接口,因为使用了该术语。 FFi是关于编程语言之间的交互,应该能够使一种语言(有适当的限制)从一种语言可用到另一种语言。可以从一种语言访问的特定库不是FFI制作的。

    • 从各种语言编程语言绑定到OpenGL
    • 来自各种语言的C库的绑定