生成python绑定,向我们提供什么方法/程序

2024-05-18 18:28:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在考虑在我的程序中使用python(CPython),既允许在我的环境中使用用户脚本,又允许我使用pyside,即qt绑定来为我的应用程序创建GUI。这些代码可以有效地分离出来,其思想是GUI python代码可以在以后快速编译(如果可能的话)。

我对python很陌生,我真的在寻找一种最有效的方法来生成可靠的绑定,并且随着项目的发展,绑定很可能会经常更改,因此要维护的额外代码绝对是最少的。我需要它,以便python类扩展具有虚拟机的c++类。

我已经研究过PyBindGen,它经常被我的库中的东西噎住,以至于它实际上没有用处。

您在这方面推荐的任何帮助/建议/链接/工作流都将非常有用。


Tags: 项目方法代码用户程序脚本应用程序环境
3条回答

现代C++使用克里夫(https://github.com/google/clif)。 它没有发现您的API,您需要用Python术语描述它。

克里夫将用最新的LLVM/CLAN编译器重新编译您的头,并为Python扩展模块生成C++源代码。

它可以理解复杂的数据结构:def f() -> dict<str, set<int>>

< >我知道只有两个项目有C++的自动绑定生成器。第一个是SWIG。正如另一个答案所说,这是一个有点旧的风格,但它的工作。第二个是Boost.Python,它本身并不自动生成绑定,但是您可以使用Boost.Pyste为自己生成绑定。它需要GCC-XML来解析原始源代码并编写Boost.Python绑定。两个选项都支持C++中的虚拟方法,这些方法可以从Python重载。

我说,我必须补充,通常,当你有约束力时,你不会盲目地把C++中的所有东西都绑定到Python中。如果你这样做,你不会从Python的侧面得到一个非常的python感。相反,您设计了希望库以Python最可能的方式使用的库,然后返回并查看如何使用可能的绑定库之一将其插入到C++代码中。例如,与其处理std::vector,不如让库调用处理Python列表或iterable。如果C++库接收到一个^ {CD2}},那么您希望用Python字典处理。如果是数组,那么numpy.ndarray可能更方便。等等。。。

也就是说,您仍然可以设计绑定,以便将维护最小化。

这是一个其他Python/C++包的列表,如果您决定进一步查看:

  1. SWIG-你已经知道了
  2. Boost.Python-这是我们通常在这里使用的-结构非常好
  3. Cython-非常简洁的语法接近Python-它们声称比Boost.Python快得多
  4. SIP-不是很广,但在那里
  5. pybind11-类似于Boosi.python的语法,紧凑的实现得益于C++ 11。

它们现在处于非活动状态:

  1. PyBindGen-声称是自2017年5月21日(2014年上一版本)以来最快的,但非活动的版本-目前在github上维护(https://github.com/gjcarneiro/pybindgen/releases
  2. ECS:Python-自2014年12月6日(v2.8)起不活动,移动到github(https://github.com/MarcusTomlinson/ECS-Python
  3. {A11}-C++设施,使编写Python扩展变得更容易——不活动?上一版本是2017年4月23日的v7.0.2CLIF -克里夫为创建各种语言的C++包装生成器提供了共同基础——不活动?回购活动不多(只有14次提交)

为了完整起见,也可以将编译后的C代码直接加载到Python中,而不必创建正式的绑定。您可以使用FFI来完成此操作 对于这两个Python模块中的任何一个:

  1. ctypes-这是Python自带的,不需要外部模块安装。
  2. cffi-这是一个新的包,灵感来自Lua JIT上的等效设计。

如果你在寻找速度,我肯定也会投给赛顿。据我所知,关于C++与Python接口的其他方法,与其他绑定工具相比,Cython的维护/更新并不那么重,而是关于工作流的“流动性”增益。(Cythonized代码认为其速度与纯C一样快,或者距离纯C不远,这也使得它非常有趣)。

无论如何,有几个好的API连接Python代码和C++(Boost.Python,…),但是我认为所有这些都会导致需要直接在C++源代码中公开方法(你们告诉我,如果我错了,或者不精确)。

另一方面,Cython将为您提供将C++ API(GUI,或任何…)严格地与曝光源(所谓的PYX扩展)隔离的可能性。最后的工作流程是:

< P> C++ +API=&编译;作为共享对象= & gt;Cython扩展(s)(导入和暴露C++特征)= &编译扩展(s)=& gt;使用扩展(扩展到Python路径)。

好消息是,您必须只维护池中的Pyx文件的变化部分,这些文件与正在演化的C++特性(其中需要被曝光的那些)有关。一开始这是一种投资,但是,以我的经验,一旦这个工作流程建立起来,就可以很直接地使整个事情变得复杂起来。

现在考虑到您需要扩展具有virtual的类并从Python重写它们(如果我正确理解了您的意思)。这是可行的。再一次,不是那么直接,但是你应该看看这个thread

坏消息:在那个特殊情况下,如果扩展Python没有重写给定的父方法,则必须创建一些额外的C++适配器/接口,以便启用父方法的调用。(注意,从Python重新定义C++暴露方法,无论是虚拟还是非,都是函数的替换,但绝对不等同于重写)。

哼,现在我又在读自己的文章了,看起来有点困惑。希望这还是有帮助的。

如果你选择Cython选项,如果你让我做的话,我可以更具体地说明你必须处理的工作流,但是我认为上面链接的线程是一个很好的起点。。。

相关问题 更多 >

    热门问题