c++ 生成python绑定,使用什么方法/程序[已关闭]

jvidinwx  于 2023-02-10  发布在  Python
关注(0)|答案(6)|浏览(109)

**已关闭。**此问题不符合Stack Overflow guidelines。当前不接受答案。

我们不允许问题寻求有关书籍、工具、软件库等的推荐。你可以编辑问题,以便可以使用事实和引用来回答问题。
三年前关闭了。
Improve this question
我正在考虑在我的程序中使用python(CPython),以允许用户在我的环境中编写脚本,并允许我使用pyside(用于c的qt绑定)为我的应用程序创建GUI。这些可以有效地分离,因为GUI python代码可以在以后进行编译以提高速度(如果可能的话)。
我对python还很陌生,我真的在寻找一种最有效的方法来生成实绑定,并且用最少的额外代码来维护,因为绑定可能会随着项目的发展而经常改变。我需要它来让python类扩展有虚值的c
类。
我已经研究过PyBindGen,它经常被我图书馆里的东西卡住,不能发挥实际作用。
您在这方面推荐的任何帮助/建议/链接/工作流程都将非常有帮助。

guykilcj

guykilcj1#

据我所知,只有少数几个项目有C的自动绑定生成器。第一个是SWIG。正如一些其他的回答已经说过的,它的风格有点旧,但它能工作。第二个是Boost.Python -它本身并不自动生成绑定,但是您可以使用Boost.Pyste来完成它,它需要GCC-XML来解析您的原始源代码并编写Boost.Python绑定,这个领域中的新成员是cppyyShiboken。所有选项都支持C中的虚方法,这些虚方法可以从Python重载。
也就是说,我必须补充一点,通常,当你绑定的时候,你应该避免盲目地把C中的所有东西都绑定到Python中--如果你这样做,你可能不会从Python方面得到一种非常Python化的感觉,相反,你应该设计你希望你的库如何在Python中使用,以最Python化的可能方式。然后你回过头来看看如何使用一个可能的绑定库把它修补到你的C代码中。例如,你更喜欢你的库调用处理Python列表或可迭代对象,而不是处理std::vector。如果你的C库接收到一个std::map,你希望用Python字典来处理它。如果它是一个数组,也许numpy.ndarray会更方便。等等...
也就是说,您仍然可以设计绑定,以便最大限度地减少维护。
下面是其他Python/C
Package 的列表,以防您决定进一步查看:

  1. SWIG-如您所知
  2. Boost.Python--这是我们在这里通常使用的--结构非常好。下面的pybind 11可能是一个更现代的选择。
  3. Cython-非常简洁的语法,接近Python -他们声称比Boost.Python快得多
  4. SIP-传播不是很大,但它就在那里
  5. pybind11-语法类似于Boost.Python,由于C++11而实现紧凑。
  6. cppyy- cppyy通过利用Cling C解释器和LLVM提供全自动、动态的Python-C绑定。它支持PyPy(原生)、CPython和 C++ 标准,直至C17(以及C20的一部分)。
  7. Shiboken-是Qt框架的一部分,可以从C或C头文件中提取信息,并生成CPython代码,允许将C或C项目引入Python。
    这些现在处于非活动状态:
  8. PyBindGen-声称是最快的,但自2017年5月21日以来处于非活动状态,上一版本于2014年发布-目前在github上维护(https://github.com/gjcarneiro/pybindgen/releases
  9. ECS:Python-不活动自2014年12月6日(v2.8)起,移至github(https://github.com/MarcusTomlinson/ECS-Python
  10. PyCXX- C++工具,使编写Python扩展更容易- * 不活动?* 最新版本是2017年4月23日的v7.0.2
  11. CLIF- CLIF为创建各种语言的C++ Package 器生成器提供了一个通用的基础- * 不活动?* repo上没有太多活动(只有14次提交)
    为了完整起见,也可以不创建正式绑定而直接将编译后的C代码加载到Python中,你可以使用FFI和下面两个Python模块中的任意一个来实现这一点:
  12. ctypes-这是Python的原生代码,不需要安装外部模块。
  13. cffi-这是一个受Lua JIT上等效设计启发的新包。
f5emj3cl

f5emj3cl2#

如果你在寻找速度,我肯定也会投Cython的票。就我所知的C和Python接口的其他方式而言,Cython与其他绑定工具相比,在"工作流的流动性"方面并没有那么繁重的维护/更新工作。(Cython化的代码认为它和纯C一样快,或者离纯C不远,这也使它非常有趣)。
无论如何,有几个很好的API可以连接Python代码和C
(Boost.Python,...),但我认为所有这些API都将导致需要直接在C源代码中公开方法(如果我错了,或者不精确,你们告诉我)。
另一方面,Cython可以让你的C
API(GUI,或者其他什么)与暴露源(所谓的. pyx扩展)严格分离。
C++ API =〉编译为共享对象=〉Cython扩展(导入和公开C特性)=〉编译扩展=〉使用扩展(添加到Python路径的扩展)。
好消息是您只需要维护. pyx文件池中与不断发展的C
特性相关的变化部分(在那些需要公开的部分中)。开始时这是一种投资,但是,根据我的经验,一旦这个工作流建立起来,它就非常直接地使整个事情变得复杂。
现在,关于你需要扩展有虚值的类,并从Python中覆盖它们(如果我没理解错你的意思的话)。这是可行的。再说一次,不是那么直接,但是你应该看看这个线程。
坏消息是:在这种特殊情况下,您必须创建一些额外的C适配器/接口,以便在扩展的python方法没有覆盖给定父方法的情况下启用父方法的调用。(注意,从python重定义一个C公开的方法,无论是否为虚方法,都是对函数的替换,但绝对不等同于覆盖)。
hummf,现在我正在读自己回来,它看起来有点混乱。希望这仍然是有帮助的。
如果你选择Cython选项,如果你问我,我可以更具体地描述你必须处理的工作流程,但我认为上面链接的线程是一个很好的起点...

q1qsirdb

q1qsirdb3#

对于现代C++,使用CLIF(https://github.com/google/clif),它不会发现你的API,你需要用Python的术语来描述它。
CLIF将使用最新的LLVM/Clang编译器重新编译头文件,并生成Python扩展模块的C++源代码。
它可以理解复杂的数据结构:def f() -> dict<str, set<int>> .

vecaoik1

vecaoik14#

对于现代C++,使用cppyy:http://cppyy.readthedocs.io/en/latest/
它基于Cling,Clang/LLVM的C解释器。绑定在运行时进行,不需要额外的中间语言。多亏了Clang,它支持C17。
具体到使用Qt的原始问题:最近的几个更新明确地支持所有KDE的绑定生成。
对于速度:PyPy本身就支持cppyy。
注:我是cppyy的主要作者。

lkaoscv7

lkaoscv75#

事实上,C++并没有太多的选项,其中一个比较老的项目是SWIG;据说它有点《双城之战》和笨拙,但是因为它已经存在很长时间了,所以它应该也涵盖了很多其他项目没有处理的东西。

eh57zj3b

eh57zj3b6#

SWIG是一个伟大的工具,可以做你想做的
http://sourceforge.net/projects/swig/

相关问题