集成Python和C ++

时间:2009-07-20 13:28:05

标签: c++ python integration

我正在学习C ++,因为它是一种非常灵活的语言。但对于像Twitter,Facebook,Delicious等互联网来说,Python似乎是一个更好的解决方案。

是否可以在同一个项目中集成C ++和Python?

11 个答案:

答案 0 :(得分:87)

将Python与C / C ++连接起来并非易事。

这里我在前一个问题上复制/粘贴previous answer,以便编写python扩展的不同方法。以Boost.Python,SWIG,Pybindgen为特色......

  • 您可以使用Python C-API在C或C ++中自行编写扩展程序。

    总而言之:除了学习如何做之外,不要这样做。要正确地做到这一点非常困难。您必须手动递增和递减引用并编写大量代码才能公开一个函数,只有很少的好处。

  • Swig

    pro:您可以为许多脚本语言生成绑定。

    缺点:我不喜欢解析器的工作方式。我不知道他们是否取得了一些进展但两年前C ++解析器非常有限。大多数时候我不得不复制/粘贴我的.h标头来添加一些%个字符,并为swig解析器提供额外的提示。

    我还需要不时地处理Python C-API(不是那么)复杂的类型转换。

    我不再使用它了。

  • Boost.Python

    亲: 这是一个非常完整的图书馆。它允许您使用C-API完成几乎所有可能的操作,但是在C ++中。我从来没有用这个库编写C-API代码。我也从未遇到过因库而导致的错误。绑定代码可以像魅力一样工作,也可以拒绝编译。

    如果您已经有一些要绑定的C ++库,它可能是目前可用的最佳解决方案之一。但是如果你只有一个小的C函数来重写,我可能会尝试使用Cython。

    缺点:如果您没有预编译的Boost.Python库,那么您将使用Bjam(替代make)。我真的很讨厌Bjam及其语法。

    使用B.P创建的Python库往往会变得肥胖。编译它们还需要很多时间。

  • Py++:这是Boost.Python变得简单。 Py ++使用C ++解析器来读取您的代码,然后自动生成Boost.Python代码。你也得到了作者的大力支持(不,不是我;-))。

    缺点:只有Boost.Python本身引起的问题。

    编辑此项目已停止使用。虽然可能仍在工作,但考虑转换可能会更好。

  • Pybindgen

    它生成处理C-API的代码。您可以在Python文件中描述函数和类,也可以让Pybindgen自动读取标题并生成绑定(为此它使用pygccxml,Py ++的作者编写的python库)。

    缺点:这是一个年轻的项目,团队规模比Boost.Python小。仍然存在一些限制:您不能公开自己的C ++异常,不能对C ++类使用多重继承。

    无论如何,这值得尝试!

  • Pyrex和Cython

    这里你不是编写真正的C / C ++,而是Python和C之间的混合。这个中间代码将生成一个常规的Python模块。

编辑2013年7月22日:现在Py ++已停产,我现在正在寻找一个好的选择。我目前正在为我的C ++库试验Cython。这种语言是Python和C之间的混合。在Cython函数中,您可以使用Python或C / C ++实体(函数,变量,对象......)。

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语言功能来简化创建新绑定的过程。它也是一个只有头的库,因此在使用它之前没有任何东西可以编译,也没有要链接的库。

我玩了一点点,使用它确实非常简单和愉快。我唯一担心的是,像Boot.Python一样,它可能会导致编译时间过长和大型库。我还没有做过任何基准测试。

答案 1 :(得分:9)

是的,鼓励和documented是可能的。我自己做了,发现它很容易。

答案 2 :(得分:3)

Python/C API Reference Manual - 想要编写扩展模块或嵌入Python的C和C ++程序员使用的API。

Extending and Embedding the Python Interpreter

  

描述了如何用C或C ++编写模块以使用新模块扩展Python解释器。这些模块可以定义新函数,也可以定义新对象类型及其方法。该文档还描述了如何将Python解释器嵌入到另一个应用程序中,以用作扩展语言。最后,它展示了如何编译和链接扩展模块,以便它们可以动态(在运行时)加载到解释器中,如果底层操作系统支持此功能。

答案 3 :(得分:3)

试试Pyrex。为Python编写C ++扩展更容易。

答案 4 :(得分:3)

我们在产品中非常成功地使用swig

基本上swig接受你的C ++代码并在其周围生成一个python包装器。

答案 5 :(得分:3)

我建议看看PyTorch如何进行整合。

答案 6 :(得分:2)

见:

使用C或C ++扩展Python

“如果您知道如何在C中编程,那么向Python中添加新的内置模块非常容易。这样的扩展模块可以做两件不能直接在Python中完成的事情:他们可以实现新的内置模块在对象类型中,它们可以调用C库函数和系统调用。

为了支持扩展,Python API(应用程序编程接口)定义了一组函数,宏和变量,可以访问Python运行时系统的大多数方面。 Python API包含标题“Python.h”,它包含在C源文件中。 “

http://www.python.org/doc/2.5.2/ext/intro.html

PS拼写为“整合”:)

答案 7 :(得分:2)

过去我使用过PyCxx http://cxx.sourceforge.net/,我发现它非常好。

它以非常优雅的方式包装python c API,使其使用起来非常简单。 在c ++中编写python扩展非常容易。它提供了清晰的示例,因此很容易上手。

我非常喜欢使用这个库,我推荐它。

答案 8 :(得分:2)

这取决于您的便携性要求。我一直在努力解决这个问题,最后我直接使用python API包装我的C ++,因为我需要一些可以在管理员只攻击一个主要工作的gcc和python安装的系统上运行的东西。

理论上Boost.Python应该是一个非常好的选择,因为Boost几乎可以在任何地方使用。不幸的是,如果您最终使用较旧的默认 python安装(我们的协作仍然支持2.4),如果您尝试使用较新版本运行Boost.Python,则会遇到问题(我们都使用Python 2.6)。由于您的管理员可能不打算安装与每个python版本对应的Boost版本,因此您必须自己构建它。

因此,如果您不介意在运行代码的每个系统上都需要一些Boost设置,请使用Boost.Python。如果您希望代码能够在任何使用Python和C ++编译器的系统上运行,请使用Python API。

答案 9 :(得分:1)

您可以在C ++中编写Python extensions。基本上Python本身是用C语言编写的,你可以用它来调用你的C代码。您可以完全访问Python对象。另请查看Boost.Python

答案 10 :(得分:1)

另一个有趣的方法是通过运行python本身来解析c ++头文件来生成python代码。 OpenCV team successfully took this approach现在他们为OpenCV库制作java包装器做了同样的事情。我发现这创建了更清晰的Python API,没有由某个库引起的限制。