整合Python和C ++
我正在学习C ++,因为它是一种非常灵活的语言。 但对于像Twitter,Facebook,Delicious等互联网的东西,Python似乎是一个更好的解决scheme。
是否有可能将C ++和Python集成到同一个项目中?
Python与C / C ++的接口不是一件容易的事情。
在这里,我复制/粘贴上一个问题的答案为不同的方法来编写一个Python扩展。 拥有Boost.Python,SWIG,Pybindgen …
-
您可以使用Python C-API自己用C或C ++编写扩展。
总之,除了学习如何去做,别这么做。 要做到这一点非常困难。 你将不得不手动递增和递减引用,并写很多代码来暴露一个函数,但是很less有好处。
-
Swig :
亲:你可以为许多脚本语言生成绑定。
缺点:我不喜欢parsing器的工作方式。 我不知道他们是否取得了一些进展,但是两年前C ++parsing器是相当有限的。 大多数情况下,我不得不复制/粘贴我的.h头文件来添加一些
%
字符,并给swigparsing器提供额外的提示。我还需要不时地处理Python C-API(不是那么)复杂的types转换。
我不再使用它了。
-
Boost.Python :
亲:这是一个非常完整的图书馆。 它允许你用C-API来做几乎所有可能的事情,但是在C ++中。 我从来没有写这个库的C-API代码。 我也从来没有遇到由于图书馆的错误。 绑定代码要么像魅力一样,要么拒绝编译。
如果您已经有一些C ++库可以绑定,那么这可能是目前最好的解决scheme之一。 但是如果你只有一个小的C函数来重写,我可能会尝试使用Cython。
缺点:如果你没有预编译的Boost.Python库,你将使用Bjam(make的replace)。 我真的讨厌Bjam和它的语法。
用BP创build的Python库往往变得肥胖。 编译它们也需要很多时间。
-
Py ++ :它的Boost.Python变得简单。 Py ++使用C ++parsing器来读取您的代码,然后自动生成Boost.Python代码。 你也得到了作者的大力支持(不,不是我;-))。
缺点:只有由于Boost.Python本身的问题。
编辑这个项目看起来停止。 虽然可能还在工作,但考虑切换可能会更好。
-
Pybindgen :
它生成处理C-API的代码。 您可以在Python文件中描述函数和类,或者让Pybindgen自动读取您的头文件并自动生成绑定(为此,它使用pygccxml,由Py ++的作者编写的python库)。
缺点:这是一个年轻的项目,比Boost.Python小一点。 还有一些限制:你不能公开你自己的C ++exception,你不能为你的C ++类使用多重inheritance。
无论如何,这是值得尝试!
-
Pyrex和Cython :
在这里你不写真正的C / C ++,而是Python和C的混合。这个中间代码将生成一个常规的Python模块。
编辑七月22 2013:现在Py ++看起来停止,我现在正在寻找一个很好的select。 我目前正在用我的C ++库的Cython实验。 这种语言是Python和C之间的混合体。在Cython函数中,您可以使用Python或C / C ++实体(函数,variables,对象等)。
Cython非常容易学习,具有非常好的性能,如果不需要接口传统的C ++库,甚至可以完全避免使用C / C ++。
但是对于C ++来说,它有一些问题。 它比Py ++更“自动化”,所以对于稳定的C ++ API(现在是我的库的情况)可能更好。 我用Cython看到的最大的问题是C ++多态性。 使用Py ++ / boost:python我可以用C ++定义一个虚拟方法,用Python覆盖它,并且在C ++中调用Python版本。 使用Cython它仍然是可行的,但是你需要明确地使用C-Python API。
编辑2017-10-06:
有一个新的, pybind11 ,类似于Boost.Python,但有一些潜在的优势。 例如,它使用C ++ 11语言function来更简单地创build新的绑定。 它也是一个只有头文件的库,所以在使用它之前没有什么东西可以编译,也没有库链接。
我玩了一下,确实非常简单和愉快的使用。 我唯一的担心就是像Boot.Python那样会导致编译时间太长和库很大。 我还没有做任何基准。
是的,这是可能的,鼓励和logging 。 我自己做了,发现它很容易。
Python / C API参考手册 – 希望编写扩展模块或embeddedPython的C和C ++程序员使用的API。
扩展和embeddedPython解释器
描述了如何用C或C ++编写模块来扩展Python解释器和新模块。 这些模块可以定义新的function,但也可以定义新的对象types及其方法。 该文档还介绍了如何将Python解释器embedded到另一个应用程序中,以用作扩展语言。 最后,它显示了如何编译和链接扩展模块,以便它们可以在运行时dynamic加载到解释器中(如果底层操作系统支持此function的话)。
尝试Pyrex 。 使编写Python的C ++扩展更容易。
我们在我们的产品中使用swig非常成功。
基本上swig需要你的C ++代码,并生成一个python包装。
我以前使用过PyCxx http://cxx.sourceforge.net/ ,发现它非常好。
它以非常优雅的方式封装了python c API,使得它非常简单易用。 在c ++中编写python扩展是很容易的。 它提供了清晰的例子,所以很容易上手。
我非常喜欢使用这个库,我推荐它。
这取决于您的可移植性要求。 我一直在为此苦苦挣扎,最后我直接用Python API封装了我的C ++,因为我需要一些适用于系统pipe理员只能攻击一个主要工作的gcc和python安装的系统。
理论上Boost.Python应该是一个非常好的select,因为Boost在任何地方都是可用的。 不幸的是,如果你最终在一个较老的默认的 python安装(我们的协作是坚持2.4)的操作系统,你会遇到问题,如果你尝试运行Boost.Python更新的版本(我们都使用Python 2.6)。 由于您的pipe理员可能不打算安装与每个Python版本相对应的Boost版本,因此您必须自己构build它。
所以如果你不介意可能需要在你的代码运行的每个系统上进行一些Boost设置,使用Boost.Python。 如果你想要在Python和C ++编译器的任何系统上工作的代码,请使用Python API。
看到这个:
用C或C ++扩展Python
“如果你知道如何用C语言编程,向Python中添加新的内置模块是相当容易的。这样的扩展模块可以做两件事情,不能直接在Python中完成:它们可以实现新的内置对象types,他们可以调用C库函数和系统调用。
为了支持扩展,Python API(应用程序员接口)定义了一组函数,macros和variables,它们提供对Python运行时系统大部分方面的访问。 Python API通过包含头文件“Python.h”被合并到C源文件中。 “
http://www.python.org/doc/2.5.2/ext/intro.html
PS这是拼写“整合”:)
另一个有趣的方法是通过运行python本身来parsingc ++头文件来生成python代码。 OpenCV团队成功地采用了这种方法 ,现在他们完成了同样的事情,为OpenCV库制作java包装。 我发现这个创build更清洁的Python API没有限制,由某个库引起的。
你可以用C ++编写Python扩展 。 基本上Python本身是用C编写的,你可以用它来调用你的C代码。 您可以完全访问您的Python对象。 另外检查出Boost.Python 。
我build议看看PyTorch如何进行整合。