如何使用标准库嵌入Python3

时间:2016-01-11 15:15:41

标签: python python-3.x embedding standard-library

我试图将Python嵌入(最终多平台)C ++应用程序中。

我的应用程序包含自己的Python实现(与blender一样)非常重要,因此它完全是自包含的。 (否则它会变成配置雷区)。

我有两个选择:

  1. 尝试在没有标准库的情况下嵌入Python3 (我已经问过here

  2. 尝试使用标准库嵌入Python3

  3. (2)需要什么?

    通过这些信息,我可以平衡每种方法的优点与设置它所需的工作量。

    我的嵌入式Python将供我自己使用(而不是任何用户区脚本) - 主要是控制流/游戏逻辑。我将需要很少的标准库 - 也许我可以通过在必要时隧道回C ++将其降低到0 - 例如,如果我需要一个随机数,我可以创建一个C ++例程并从Python访问它。我已经涵盖了所有这些。

    然而,它开始看起来好像即使最小的安装也必须包含一些stdlib组件,这提示了一个问题:“如果我必须包含一些,也许最好包括所有!”

3 个答案:

答案 0 :(得分:0)

您正在寻找Boost.Python

这是一个 C ++库,可以在C ++和Python编程语言之间实现无缝互操作性,在我看来,这应该满足您的需求,除非您尝试实现其他目的

它还有一种将python解释器嵌入到C ++代码中的机制,可以参考this link(URL不是特定于发行版)来深入研究这些可能性。

P.S。我更少相信重新发明轮子,而不是重新使用。

答案 1 :(得分:0)

我想你已经仔细检查了如何在另一个应用程序中嵌入Python(here你会看到一些内容,包括嵌入python2,但在我看来也适用于python3)

有不同类型的嵌入:

  • 非常高级嵌入
  • 超高级别嵌入
  • Pure Embedding
  • 在C ++中嵌入Python

由于您的问题与“在C ++中嵌入Python”有关,您可以阅读:

  

也可以将Python嵌入到C ++程序中; 正是如何   这样做取决于所使用的C ++系统的细节;在   一般来说,你需要用C ++编写主程序,并使用   用于编译和链接程序的C ++编译器。没有必要   使用C ++重新编译Python本身。

一方面你说“(最终是多平台)C ++应用程序”,另一方面你有“如何完成这将取决于所使用的C ++系统的细节“,您可以解释一下所使用的C ++系统的更多细节吗?

您可能还会发现一些与使用here或其他pybind11 module相关的提示old page,其中介绍了如何在C / C ++中嵌入Python和导入模块(python2.6但是我希望你可以从中找到灵感。

总结:

  

你显然需要Python的开发包才能拥有   Python包含目录

答案 2 :(得分:-1)

由于这并没有真正得到答案,我会为后人提供这个。我也无法访问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/

使用python documentation中的以下代码创建一个新的c ++源文件(embeddedpython.cpp),但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,ctime\n"
                       "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。用这种方法,&#34;家庭&#34;目录必须包含在您的部署中,并且必须将环境变量PYTHONHOME设置为在执行任何与python相关的代码之前指向它。