如何在多平台C++框架(JUCE)中嵌入Python?

1 投票
3 回答
2074 浏览
提问于 2025-04-18 20:08

我正在用JUCE设计音乐训练游戏。JUCE是一个可以在多个平台上使用的C++框架,它让我能在音频和视觉方面进行底层编程。

不过,我的游戏逻辑(控制流程和数据处理)是用Python写的。这个部分比较复杂,我希望能不断修改它,以便尝试不同的游戏玩法。Python非常适合这种快速原型开发。

所以,我想让我的C++代码(可以在Windows、Mac、Linux、iOS和Android上运行)启动一个Python运行环境,给它一个.py文件,然后调用这个文件里的各种函数。同时,我也希望能从.py文件中调用回C++的代码。

这里有相关的官方Python文档:https://docs.python.org/2/extending/extending.html

还有一篇CodeProject的文章:http://www.codeproject.com/Articles/11805/Embedding-Python-in-C-C-Part-I

不过,这两者似乎都没有解决跨平台的问题。

这个技术的关键在于链接libpython.a这个库,并且包含一些头文件,这些文件里有启动运行环境、加载脚本、执行Python代码等各种函数。

但这个libpython.a肯定需要针对每个平台单独编译吧?如果是这样的话,这就不是一个很干净的解决方案。那么,我能不能把Python的源代码加到我的项目里,然后让它编译出.a文件呢?

我该怎么做呢?

编辑:https://wiki.python.org/moin/boost.python/EmbeddingPython

编辑2:我觉得把完整的CPython源代码引入进来有点过于复杂了——应该有人做过一些简化版的Python实现,用C/C++写的,不支持系统调用、多线程或其他复杂功能,只是逐行执行Python语法。我在查看https://wiki.python.org/moin/PythonImplementations,但没有找到明显的合适选项。

编辑3:https://github.com/micropython/micropython应该被加到最后一页,但看起来这也不是我想要的。

3 个回答

0

我正在使用SWIG把Python嵌入到我的C++应用程序中,同时也想扩展它,也就是说,我希望在我的应用程序外部用Python访问我的C++接口。SWIG和Python都是跨平台的,所以这不是个问题。SWIG的一个主要优点是它可以为很多编程语言生成绑定代码。此外,还有很多C++代码的封装工具可以使用,比如boost.python或cython。

你可以查看这些StackOverflow上的链接:

扩展Python - 使用SWIG,而不是SWIG或Cython

将C++ API暴露给Python

或者你也可以选择更复杂的方式,直接使用Python/C API。

0

我最近决定做一个项目,把C++和Python结合起来,这样就能享受到两者的优点。我的想法是用Python快速开发类和函数,原因很明显,但我也希望能在Python中调用C++的代码(原因同样明显)。所以,我建议你不要把Python嵌入到C++框架中,而是把C++框架嵌入到Python项目里。为了做到这一点,你只需要写一些非常简单的接口文件,然后让Swig来处理接口的部分。

如果你想从头开始,有一个很不错的工具叫做cookiecutter,可以用来生成项目模板。你可以选择cookiecutter-pypackage或者cookiecutter-pylibrary,后者在前者的基础上有所改进,具体可以参考这里。有趣的是,你也可以用cookiecutter的代码来生成C++项目的结构。这个空项目使用CMake构建系统,我认为这是开发跨平台C++代码的最佳框架。接下来,我需要决定这个混合项目的目录结构,所以我之前的一篇帖子详细描述了这一点。祝你好运!

3

在Python的文档中,有一整章专门讲解如何把Python解释器嵌入到其他应用程序中。

嵌入Python和扩展Python有点像,但又不完全一样。主要的区别在于,当你扩展Python时,应用程序的主程序仍然是Python解释器,而如果你嵌入Python,主程序可能和Python没有任何关系——相反,应用程序的某些部分会偶尔调用Python解释器来运行一些Python代码。

所以,如果你在嵌入Python,你就是在提供自己的主程序。这个主程序需要做的一件事就是初始化Python解释器。至少,你需要调用一个函数Py_Initialize()。你还可以选择性地传递命令行参数给Python。之后,你可以在应用程序的任何部分调用这个解释器。

调用解释器的方法有几种:你可以把包含Python语句的字符串传给PyRun_SimpleString(),或者你可以传递一个标准输入输出文件指针和一个文件名(仅用于错误信息的识别)给PyRun_SimpleFile()。你也可以调用之前章节中描述的低级操作来构建和使用Python对象。

在源代码分发包的Demo/embed/目录中,可以找到一个简单的嵌入Python的示例。

撰写回答