我正试图将Python嵌入一个(最终是多平台的)C++应用程序中。
重要的是,我的应用程序包含自己的Python实现(与blender相同),这样它就完全独立了。(否则就会成为配置雷区)。
我有两个选择:
-
尝试在没有标准库的情况下嵌入Python3(我在这里问过)
-
尝试用标准库嵌入Python3
(2)需要什么?
有了这些信息,我将能够平衡每种方法的优点与建立它所需的努力。
我的嵌入式Python将供我自己使用(而不是任何userland脚本)——主要控制流/游戏逻辑。我只需要很少的标准库——也许我可以在必要的时候通过隧道返回到C++来将其减少到0——例如,如果我需要一个随机数,我可以创建一个C++例程并从Python访问它。我已经涵盖了所有这些。
然而,看起来即使是最简单的安装也必须包含一些stdlib组件,这引发了一个问题:"如果我必须包含一些,也许最好包含所有!"
由于这并没有真正的答案,我将为子孙后代提供这个答案。我也无法访问Mac,所以它对你来说可能与Linux有点不同。此外,必须安装所需的依赖项才能正常工作,但这通常很容易弄清楚。
创建一个工作目录
mkdir ~/embeddedpython
cd ~/embeddedpython
下载Python源
wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tgz
为Python 创建安装目录
mkdir ./installation
提取下载的源文件
tar xvf Python-3.6.1.tgz
输入新创建的源目录
cd Python-3.6.1
配置Python以安装在我们的安装目录中
./configure --prefix="/home/<username>/embeddedpython/installation"
制作并安装Python
make && make install
返回到您的工作目录
cd ..
创建一个新的PYTHONHOME目录,其中库将驻留
mkdir home && mkdir home/lib
将Python库复制到我们的新主目录
cp -r ./installation/lib/python3.6 ./home/lib/
使用以下代码创建一个新的c++源文件(embeddedpython.cpp),该代码取自python文档,setenv
函数调用除外。
#include <Python.h>
#include <cstdlib>
int main(int argc, char *argv[])
{
setenv("PYTHONHOME", "./home", 1);
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctimen"
"print('Today is', ctime(time()))n");
if (Py_FinalizeEx() < 0) {
exit(120);
}
PyMem_RawFree(program);
return 0;
}
编译并运行
g++ embeddedpython.cpp -I ./installation/include/python3.6m/ ./installation/lib/libpython3.6m.a -lpthread -ldl -lutil
./a.out
> Today is Fri Apr 14 16:06:54 2017
从现在开始,它是标准的嵌入式python。使用此方法,部署中必须包含"home"目录,并且必须将环境变量PYTHONHOME
设置为在执行任何与python相关的代码之前指向该目录。
您正在寻找Boost.Python
这是一个C++库,它实现了C++和Python编程语言之间的无缝互操作性,在我看来,这应该满足您的需求,除非您正在尝试实现其他目标。
它还有一个将python解释器嵌入C++代码的机制,可以参考这个链接(URL不是特定于发行版的)来深入研究这种可能性。
附言:我不太相信重新发明轮子,而更相信可重复使用。
我想你已经仔细检查了如何在另一个应用程序中嵌入Python(在这里你会看到一些内容,包括嵌入Python 2,但在我看来,对Python 3也是如此)
有不同类型的嵌入:
- 甚高级别嵌入
- 超高级别嵌入
- 纯嵌入
- 用C语言嵌入Python++
由于您的问题与"在C++中嵌入Python"有关,您可以阅读以下内容:
也可以将Python嵌入到C++程序中确切地说这将取决于所使用的C++系统的详细信息;在里面一般情况下,您需要用C++编写主程序,并使用C++编译器来编译和链接您的程序。没有必要使用C++重新编译Python本身。
一方面你说"(最终是多平台的)C++应用程序",另一方面你又说"这将取决于所用C++系统的细节,所以你能解释一下所用C++的更多细节吗?"?
你也可以在这里找到一些关于使用pybind11模块的提示,或者其他关于如何在C/C++中嵌入Python和导入模块的旧页面(python2.6,但我希望你能从中找到灵感)
总结:
您显然需要Python的开发包才能Python包含目录