【问题标题】:Extending Python with C/C++使用 C/C++ 扩展 Python
【发布时间】:2010-11-07 18:12:18
【问题描述】:

谁能给我一些关于使用 C/C++ 扩展 Python 的工具或软件的提示?谢谢。

【问题讨论】:

  • 当你阅读docs.python.org/c-api时你遇到了什么问题?
  • Cython 是一个不错的选择!我实际上写了一篇关于它的小帖子,涵盖了从编写 Cython 源文件到构建它们的所有细节,编写 setup.py - 基本上所有你需要用 Cython 包装 C/C++ 库:martinsosic.com/development/2016/02/08/…

标签: c++ python c


【解决方案1】:

Python 网站本身有一个很棒的set of examples,还有API documentation。这就是我在需要编写 C 扩展时使用的全部内容。

【讨论】:

  • 哦,我以为你的意思是比喻性的,谢谢你的澄清
  • 如果库不是特别大(如 QT 或 WxWidgets),手写代码是最好的。
【解决方案2】:

我将为 C++ 内容添加对 Boost.Python 的强制性引用。

【讨论】:

  • 我几天前开始使用 boost.python 并且已经开始运行了。
【解决方案3】:

我们使用 SWIG 来包装我们的 C/C++ 库,以便在 Python 中使用。效果很好。

http://www.swig.org/

【讨论】:

    【解决方案4】:

    我看到没有人指出我最喜欢的包装 C++ 代码的解决方案之一,SIP(我相信它也适用于包装 C,就像 SWIG 和不同的 Boost,但我从来没有那样使用它)。它是 Riverbank Software 为制作 PyQt 而开发的工具,PyQt 是出色的 Qt C++ 跨平台框架的 Python 接口——因此,如果您的 C++ 代码使用任何 Qt 功能,它是一个自然的选择,就像 Boost Python 是您的 C++ 代码的自然选择一样使用 Boost。

    SWIG 是我们在工作中使用的(这是 10 年前做出的合理决定;-),并且具有理论上的优势,它还可以包装 C 或 C++ 代码以供 Java、Perl、Tcl 等使用——但如果你只关心 Python,就很难看到任何东西让它脱颖而出。

    如果您只是包装现有的 DLL/so,除了 Cython,其他答案已经指出(我赞同,但是 - 这些天变化非常快,所以如果您需要更稳定的东西,请小心),考虑标准功能模块ctypes——我不会将它用于非常广泛的工作(C 或 C++ 编译器会指出您的“oops”错误可能会导致 ctypes 运行时崩溃),但对于小型工作来说它很棒(而且非常方便,因为它带有标准的 Python 发行版!-)。

    优秀的旧 C API 还没有死 - 今天刚刚见到了 Case,他最近一直在为我的优秀开源项目 gmpy 进行大部分运行,我们一起决定坚持C API 至少用于 gmpy 的下一个版本——当它稳定时,我们会考虑切换到 Cython,但我们同意现在切换还为时过早。 (我们甚至没有想到任何其他替代方案,因为 gmpy 的主要观点是尽可能快地做到这一点!-)。

    【讨论】:

    • 您如何看待与 PySide 相当的 Siboken? pyside.org/docs/shiboken
    • @Craig,还没有尝试过,我计划下次需要做一些 Qt 工作时(所以给我一个尝试 PySide 的现实机会)。
    • 抱歉打错字了,我的意思是“Shiboken”。 PySide 听起来很有希望。我很抱歉他们不得不重新发明轮子。
    【解决方案5】:

    有很多解决方案。一般来说,如果可能的话,你应该避免它,因为编写 C 扩展是乏味的。通常,有必要使用 3rd 方库。在这种情况下,我认为今天的获胜解决方案是cython

    Cython 是一种“看起来像 python”的语言,但可以通过使用可选类型来加快速度。你可以在里面直接调用 C 函数,并且大部分引用计数(C 扩展中的难题)都是自动完成的。根据我的经验,它比 boost.python、swig 或 ctypes 好得多:

    • boost.python 仅适用于包装 C++ 扩展恕我直言。我觉得它太复杂了,当出现问题时很难调试。
    • swig 有相当多的开销,并且不会产生好的代码。它适用于几个函数,但非平凡的扩展通常使用类型映射,并且语法很快就会变得丑陋

    使用 cython,您可以使用 python 对象(列表、字典等)来包装您的 C 库。当然,如果您出于速度原因需要编写自己的扩展,它也非常有用。在科学 python 社区中,我认为 cython 已成为需要速度的首选工具。

    【讨论】:

    • 在不知道 OP 首先要这样做的原因的情况下说“如果可能,你应该避免它”是错误的。 Python 支持 C 扩展是有原因的,因为有时 C 扩展是最好的解决方案,在这种情况下不应该避免。根据上下文,ctypes 也比 cython 有很多优势,如果没有这些优势,说一个更好是错误的(参见stackoverflow.com/questions/1942298/…
    【解决方案6】:

    我过去使用过pycxx,我非常喜欢使用这个库。

    在我看来,它比 SWIG 更容易使用。我无法与 boost.python 相比,因为我从未真正使用过 boost。我认为 pycxx 比 boost.python 轻,但我可能错了。

    pycxx 的关键在于它是 python c api 的 c++ 包装器。它是面向对象的,它隐藏了所有困难的机制。对于 Python 程序员来说,这非常直观。它非常易于使用,并且有一些很好的入门示例。

    我确实推荐 pycxx 作为在 c++ 中制作 python 扩展的一等公民。

    【讨论】:

      【解决方案7】:

      是的,你需要这个:http://www.python.org/doc/ext/

      当然还有一个 C/C++ 编译器。

      如果您描述您正在尝试做什么,以及您正在制作什么样的扩展,我相信人们可以为您提供更多信息。

      如果您想这样做,可以使用 SWIG 之类的东西来包装库。如果您只是想要加速,C 通常是答案,但并非总是如此,等等。

      【讨论】:

        【解决方案8】:

        我很惊讶还没有人提到pybind11。 Pybind11 是amazing!

        来自他们的文档:

        pybind11 是一个轻量级的纯头文件库,它在 Python 中公开 C++ 类型,反之亦然,主要用于创建现有 C++ 代码的 Python 绑定。它的目标和语法类似于 David Abrahams 的优秀 Boost.Python 库:通过使用编译时自省来推断类型信息,从而最大限度地减少传统扩展模块中的样板代码。

        ...

        将此库视为 Boost.Python 的一个小型自包含版本,其中剥离了与绑定生成无关的所有内容。如果没有 cmets,核心头文件只需要大约 4K 行代码,并且依赖于 Python(2.7 或 3.x,或 PyPy2.7 >= 5.7)和 C++ 标准库。

        查看 pybind11 github repo,有大量信息,以及 featuresgoodies 的完整列表。

        可以在here找到带有示例的文档。

        【讨论】:

          【解决方案9】:

          也许this example 有帮助。我认为这很简单:)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-01-05
            • 1970-01-01
            • 2017-06-11
            • 2011-03-31
            • 1970-01-01
            • 2021-09-27
            • 2017-12-16
            相关资源
            最近更新 更多