如何将一种语言(例如python)绑定到另一种语言(例如C++)?

2022-09-03 05:10:27

我远不是python专家,但我一直听到这个,关于它的C / C++绑定。这个概念是如何工作的,Python(和Java)如何绑定到基于C的API,如OpenGL?这些东西对我来说一直是个谜。


答案 1

口译员用C89写与反思,谁知道?


我有一种感觉,你正在寻找机制的解释,而不是指向API的链接或有关如何编码的说明。所以,据我所知...

主解释器通常用C编写,并且是动态链接的。在动态链接的环境中,即使C89也具有一定程度的反射行为。特别是,和 调用将加载动态(通常是 ELF)库,并查找由字符串命名的符号的地址。给出该地址,解释器可以调用一个函数。即使静态链接,解释器也可以知道C函数的地址,其名称被编译到其中。dlopen(3)dlsym(3)

因此,只需让解释的代码告诉解释器调用特定本机库中的特定本机函数即可。

该机制可以是模块化的。用脚本编写的解释器扩展库本身可以调用和的裸挂,并连接到解释器从未知道的新库。dlopen(3)dlsym(3)

为了按值传递简单对象,一些原型函数通常允许各种调用。但是对于结构化数据对象(想象一下stat(2)),包装器模块需要知道数据的布局。在某些时候,无论是在打包扩展模块还是安装扩展模块时,C 接口模块都包含相应的头文件,并与手写代码一起构造一个接口对象。这就是为什么您可能需要安装类似的东西,即使您已经在系统上安装了;只有包具有重新编译链接代码所需的 .h 文件。libsqlite3-devsqlite3-dev

我想我们可以总结一下:“这是用蛮力和无知完成的”。:-)


答案 2

主要的一般概念被称为FFI,“外国函数接口” - 对于Java来说,它是JNI,对于Python来说,它是“Python C API”,对于Perl来说,它是XS,等等,等等,但我认为给你一般的艺术术语来帮助你更彻底地研究它是很重要的。

给定一个FFI,你可以编写(例如)直接尊重它的C程序,和/或者你可以有代码生成器,从他们收到的元信息中生成这样的C代码和/或从用其他语言编写的代码中反省(通常有一些帮助,例如,驱动SWIG代码生成器,你通常会用特定于SWIG的额外信息来装饰C头文件中的信息,以获得更好的包装器)。.h

还有一些特殊的语言,如Cython,Python的“扩展子集”,旨在轻松生成FFI代码,同时匹配Python的大部分语法和语义 - 对于大多数Python程序员来说,这可能是编写Python扩展模块的最简单方法,该模块可以编译成快速的机器代码,并可能使用一些现有的C可调用库。

ctypes方法与传统的FFI方法不同,尽管它自称为“Python的外部函数库” - 它依赖于DLL中可用的外部代码(或等效的,例如Linux中的动态库),并在运行时生成和执行代码以到达这种动态加载的C代码(通常都是通过Python中的显式编程完成的 - 我不知道基于内省和ctypes代码的ctypes包装器。 世代,然而)。方便避免安装任何特殊的东西,用于使用Python访问现有DLL的简单任务,但我认为它不像FFI“基于链接器”的方法那样扩展(因为它需要更多的运行时消耗,等等)。除了Python的ctype之外,我不知道这种方法的任何其他实现,针对其他语言(我想有些确实存在,考虑到今天DLL和.so打包的流行,并且会好奇地了解它们)。.so