我想从Python应用程序调用C库。我不想包装整个API,只想包装与我的案例相关的函数和数据类型。在我看来,我有三个选择:
我不确定是2)还是3)是更好的选择。3)的优点是ctypes
是标准库的一部分,生成的代码将是纯Python——尽管我不确定这种优点到底有多大。
两种选择有更多的优点/缺点吗?你推荐哪种方法?
编辑:感谢您的回答,它们为任何想做类似事情的人提供了一个很好的资源。当然,这个决定还是要对一个案子做出的,没有人会回答“这是正确的事情”。对于我自己的情况,我可能会使用ctypes,但我也期待在其他项目中试用Cython。
由于没有一个真正的答案,接受一个答案有点武断;我选择了FogleBird的答案,因为它提供了对ctypes的一些很好的洞察,而且它也是目前投票率最高的答案。然而,我建议阅读所有的答案,以获得一个良好的概述。
再次感谢。
Cython本身是一个非常酷的工具,非常值得学习,并且与Python语法惊人地接近。如果你用Numpy做任何科学计算,那么Cython就是一种方法,因为它与Numpy集成用于快速矩阵运算。
Cython是Python语言的超集。您可以向它抛出任何有效的Python文件,它将弹出一个有效的C程序。在本例中,Cython将把Python调用映射到底层的CPython API。这可能会导致50%的加速,因为您的代码不再被解释。
要获得一些优化,您必须开始告诉Cython有关代码的其他事实,例如类型声明。如果你说得够多,它可以将代码归结为纯C,也就是说,Python中的for循环变成了C中的for循环,在这里你将看到巨大的速度提升。您也可以在这里链接到外部C程序。
使用Cython代码也非常简单。我觉得这本手册听起来很难。你真的只是:
然后您可以在Python代码中
import mymodule
,完全忘记它可以编译成C无论如何,因为Cython是如此容易设置和开始使用,我建议尝试看看它是否适合您的需要。如果它不是你要找的工具,那就不是浪费。
ctypes
是您快速完成任务的最佳选择,在您仍在编写Python时与之合作是一种乐趣!我最近包装了一个FTDI驱动程序,用于使用ctypes与USB芯片通信,非常棒。我在不到一个工作日的时间里完成了所有的工作。(我只实现了我们需要的功能,大约15个功能)。
我们以前使用第三方模块PyUSB也是为了同样的目的。PyUSB是一个实际的C/Python扩展模块。但是PyUSB在阻塞读写时并没有释放GIL,这给我们带来了问题。所以我使用ctypes编写了我们自己的模块,它在调用本机函数时释放GIL。
需要注意的一点是,ctypes不会知道您正在使用的库中的
#define
常量和内容,只知道函数,因此您必须在自己的代码中重新定义这些常量。下面是一个代码的最终外观示例(很多代码被剪掉了,只是想向您展示它的要点):
有人做了各种选择。
如果我不得不用大量的类/模板来包装C++库,我可能会更加犹豫,但是cType与结构非常好,甚至可以将{a4}导入到Python中。警告:Cython核心开发者的意见。
我几乎总是推荐Cython胜过ctypes。原因是它有一个更平滑的升级路径。如果使用ctypes,很多事情一开始都会很简单,用普通的Python编写FFI代码当然很酷,不需要编译、构建依赖项等等。然而,在某个时刻,您几乎肯定会发现,您必须经常调用C库,无论是在循环中还是在一系列较长的相互依赖的调用中,您都希望加快调用速度。在这一点上,您将注意到不能对ctypes执行此操作。或者,当您需要回调函数并且发现Python回调代码成为瓶颈时,您希望加快它的速度,并/或将它向下移动到C中。同样,不能对ctypes执行此操作。因此,您必须在此时切换语言并开始重写部分代码,可能会将Python/ctypes代码反向工程为纯C,从而破坏了首先使用纯Python编写代码的全部好处。
使用Cython,OTOH,您可以完全自由地使包装和调用代码尽可能薄或厚。您可以从普通Python代码向C代码的简单调用开始,Cython将它们转换为本地C调用,而不需要任何额外的调用开销,并且Python参数的转换开销极低。当您注意到在某个点上需要更高的性能时,如果您对C库进行了太多代价高昂的调用,您可以开始用静态类型注释您周围的Python代码,并让Cython直接将其优化为C。或者,可以开始用Cython重写部分C代码,以避免调用,并在算法上专门化和收紧循环。如果需要快速回调,只需编写一个带有适当签名的函数,并将其直接传递到C回调注册表。同样,没有开销,而且它提供了简单的C调用性能。而且在Cython的代码中,你不能很快地得到代码的可能性要小得多,你仍然可以考虑重写C(或C++或FORTRAN)中真正重要的部分,并从Cython代码自然地和本地地调用它。但是,这确实是最后的选择,而不是唯一的选择。
所以,ctypes很适合做一些简单的事情,并且能够快速地运行一些东西。然而,一旦事情开始发展,你很可能会发现你最好从一开始就使用Cython。
相关问题 更多 >
编程相关推荐