将Python嵌入到C ++中

时间:2016-01-04 00:10:26

标签: python c++ python-embedding

如果这个问题措辞更好/需要分成许多问题,请提醒我

我需要打包Python脚本以便将它们作为单个可执行文件(理想情况下)发送,或者将单个可执行文件作为支持文件(非理想情况下)发送。

我见过py2app和py2exe。它们不符合我的要求,因为我正在寻找一种方法来执行此操作,并且将来可能需要让打包的脚本与它们正在运行的可执行文件进行交互。

最好的方法是什么?我要嵌入的脚本甚至可能需要多个文件,这使我确定的事情变得复杂。

如果我希望将来使用除CPython之外的解释器(即:PyPy或Stackless),那么该过程是否会有所不同(除了C ++可执行文件中的API调用之外)?

是否必须在运行该软件包的计算机上安装Python,或嵌入 Python是否意味着它是完全嵌入的?我在Python Wiki上看到了一些关于Py_SetPythonHome()的内容,它会告诉我它需要安装Python(或至少它的库)。我是对的吗?

3 个答案:

答案 0 :(得分:2)

使用--onefile选项的

PyInstaller会将所有内容放在一个文件中,但启动时间会稍微多一点。我担心它与PyPy不兼容,但使用Stackless使它工作并不是那么棘手。

祝你好运!

答案 1 :(得分:0)

您确定需要嵌入Python文件吗?

我问,因为你提到你想把Python文件打包为单个可执行文件。无法在目标计算机上安装Python,并且由于Python脚本本身就是可执行文件,因此您只需要启动它们。一个主python脚本可以启动所有其余的脚本。

否则你应该在C ++中查看可以运行Python脚本的内容。然后让master python脚本运行所有其他脚本。

答案 2 :(得分:0)

是的,你可以!

最简单的是使用最新的Python3 <OS> <arch> embeddable zip file,其中包含.so / .dll和所有模块。

说明在这里:https://docs.python.org/3/extending/embedding.html

#include <Python.h>

int
main(int argc, char *argv[])
{
    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");
    Py_Finalize();
    PyMem_RawFree(program);
    return 0;
}

更棘手的部分是C ++代码和Python代码之间的通信。

如果你只需要来回传递一些字符串,这是微不足道的,但如果你想要一个非常紧密的整合,那么你可能需要其中一些:

  • 在(C ++代码,C ABI)中创建一个Python模块并注入它 - 这意味着Python将能够运行import yourmod; yourmod.yourfunc(...),它将运行您的C ++自定义代码和/或
  • 从C ++(反向)https://stackoverflow.com/a/3310608/705086
  • 解析并调用Python函数

单个可执行文件

如果你没有安装程序,并且真的不希望有一堆.DLL / .so / etc,那么它就是例如在这里Merge DLL into EXE?以及它的ABI特定,Windows将有一种方式,另一种Linux等,你可能必须覆盖Python的导入机制(因此它不会在文件系统中查找dll / so) - 此时,您也可以使用 PyInstaller 或者将PyInstaller扩展/合并到您的应用程序中。请研究https://github.com/pyinstaller/pyinstaller/tree/develop/bootloader/src并评估可能的难度

PyPy

简单嵌入是可以http://doc.pypy.org/en/latest/embedding.html,但单文件嵌入不是。您可以破解PyPy源并构建自定义可嵌入对象,但您是第一个这样做的人:)

Stackless的

应该像普通的CPythion一样简单