我远不是一个python专家,但我一直听到这个,关于它的C/C++绑定.这个概念是如何工作的,以及Python(和Java)如何绑定到基于C的API(如OpenGL)?这件事对我来说一直是个谜.
我有一种感觉,你正在寻找机制的解释,而不是API的链接或如何编码它的说明.所以,据我所知...
主解释器通常用C语言编写,并且是动态链接的.在动态链接的环境中,即使C89也有一定的反射行为.特别是,dlopen(3)
和dlsym(3)
调用将加载动态(通常是ELF)库并查找由字符串命名的符号的地址.给出那个地址,解释器可以调用一个函数.即使是静态链接,解释器也可以知道其名称被编译到其中的C函数的地址.
那么,解释代码告诉解释器调用特定本机库中的特定本机函数只是一个简单的问题.
该机制可以是模块化的.在脚本中编写的解释器扩展库本身可以调用裸挂钩dlopen(3)
,dlsym(3)
并连接到解释器从不知道的新库.
对于按值传递简单对象,一些原型函数通常允许各种调用.但是对于结构化数据对象(想象stat(2)),包装器模块需要知道数据的布局.在某些时候,无论是打包扩展模块还是安装扩展模块,C接口模块都包含相应的头文件,并与手写代码一起构造一个接口对象.这就是为什么你可能需要安装类似的东西,libsqlite3-dev
即使你已经sqlite3
在你的系统上; 只有-dev
包具有重新编译链接代码所需的.h文件.
我想我们可以这样说:"这是用蛮力和无知完成的".:-)
主要的一般概念称为FFI,"外部函数接口" - 对于Java它是JNI,对于Python它是"Python C API",对于Perl它的XS等等,但我认为给你一般的重要性艺术术语可以帮助您更彻底地研究它.
给定FFI,您可以编写(例如)直接尊重它的C程序,和/或您可以使用代码生成器从他们接收的元信息中生成这样的C代码和/或从其他语言编写的代码中反省(通常有一些帮助,例如,为了驱动SWIG代码生成器,您通常会.h
使用特定于SWIG的额外信息来装饰C头文件中的信息以获得更好的包装器.
还有一些特殊语言,如Cython,Python的"扩展子集",旨在轻松生成FFI代码,同时匹配Python的大部分语法和语义 - 对于大多数Python程序员来说,编写Python扩展通常是最简单的方法.编译为快速机器代码的模块,可能使用一些现有的C可调用库.
这种ctypes
方法与传统的FFI方法不同,虽然它自我描述为"Python的外来函数库" - 它依赖于DLL中的外来代码(或等效的,例如.so
Linux中的动态库),并在运行时生成并执行代码以达到这种动态加载的C代码(通常都是通过Python中的显式编程完成的 - 我不知道基于内省和ctypes代码生成的ctypes包装器).方便避免为使用Python访问现有DLL的简单任务安装任何特殊功能,但我认为它不会像FFI"基于链接器"的方法一样扩展(因为它需要更多的运行时间等等) .我不知道这种方法的任何其他实现,针对其他语言,超出Python的ctypes(我想有些确实存在,考虑到今天DLL和.so包装的流行,并且很想知道它们).