Python 非平凡的 C++ 扩展

Posted

技术标签:

【中文标题】Python 非平凡的 C++ 扩展【英文标题】:Python non-trivial C++ Extension 【发布时间】:2009-08-12 14:36:05 【问题描述】:

我有相当大的 C++ 库和几个支持它的子库,我需要把整个东西变成一个 python 扩展。我使用 distutils 是因为它需要跨平台,但如果有更好的工具,我愿意接受建议。

有没有办法让 distutils 先编译子库,然后在从主库创建扩展时链接它们?

【问题讨论】:

【参考方案1】:

我在我们的产品中使用了一个庞大的 C++ 库来做到这一点。有几种工具可以帮助您自动完成编写绑定的任务:最流行的是SWIG,它已经有一段时间了,在很多项目中都使用过,而且通常效果很好。

SWIG 最大的问题(在我看来)是 SWIG 本身的 C++ 代码库委婉地说真的相当粗鲁。它是在 STL 之前编写的,并且有自己的半动态类型系统,现在只是陈旧而摇摇欲坠。除非您不得不陷入困境并对核心进行一些修改(我曾经尝试添加 doxygen -> docstring 转换),否则这无关紧要,但如果您这样做了,祝您好运!人们还说 SWIG 生成的代码效率不高,这可能是真的,但对我来说,我从来没有发现 SWIG 调用自己足以成为担心它的瓶颈。

如果 SWIG 不能让您的船浮起来,您还可以使用其他工具:boost.python 也很受欢迎,如果您已经在 C++ 代码中使用了 boost 库,这可能是一个不错的选择。缺点是编译时间很长,因为它几乎都是基于 c++ 模板的。

这两种工具都需要您预先做一些工作,以便定义要公开的内容以及完成方式。对于 SWIG,您提供的接口文件类似于 C++ 头文件,但被精简了,并提供了一些额外的指令来告诉 SWIG 如何翻译复杂类型等。编写这些接口可能很乏味,因此您可能需要查看类似 pygccxml 的内容帮助您为您自动生成它们。

那个包的作者实际上写了另一个你可能喜欢的扩展:py++。这个包做了两件事:它可以自动生成绑定定义,然后可以将其馈送到 boost.python 以生成 python 绑定:基本上它是大多数人的完整解决方案。如果您没有特别特殊或难以满足的要求,您可能希望从那里开始。

其他一些可能作为参考有用的问题:

Extending python - to swig or not to swig SWIG vs CTypes Extending Python with C/C++

您还可以找到方便的 Python 绑定生成工具this comparison。正如亚历克斯在 cmets 中指出的那样,它现在已经相当老了,但至少让你对风景有了一些了解......

就如何驱动构建而言,您可能想看看 distutils 更高级的构建工具:如果您想坚持使用 Python,我强烈推荐 Waf 作为框架(其他人会告诉您 @987654330 @ 是要走的路,但相信我,它的速度非常慢:我已经去过那里又回来了!)......这需要一点学习,但是当你了解它时,它会非常强大。而且由于它是纯 Python,它将与您在构建过程中拥有的任何其他 Python 代码完美集成(例如,您最终使用 Py++)...

【讨论】:

请注意,您引用为“此比较”的 CERN 报告已超过 6 年,因此必须谨慎对待 (!)。尤其是 SIP,这些年来已经很多发展了,所以今天非常值得考虑。

以上是关于Python 非平凡的 C++ 扩展的主要内容,如果未能解决你的问题,请参考以下文章

如何使用非平凡(POD)类的缓冲区协议实现 pybind11

非程序员选择学习C++还是Python?

非程序员选择学习C++还是Python?

Python:C++ 扩展返回多个值

C++使用boost.python编写Python扩展

如何在 boost::python 扩展模块中正确组合 C++ 和 Python 代码?